问题描述
我是 Scala 的初学者,但我想知道为什么以下内容会在 Scala 3 中编译?
import scala.language.strictEquality
case class C(x: String => String) derives CanEqual
这是否应该失败,因为 CanEqual
未在 String => String
上定义,因此无法导出?
解决方法
不应该。
简单地说,这里使用 derives CanEqual
只是让编译器知道将 ==
或 !=
与 C
的实例一起使用是合法的。编译器将为 CanEqual
本身添加一个 C
实例。
泛型类(类型构造函数)的情况有所不同,因为 with CanEqual
派生 CanEqual
需要所有类型参数都存在 CanEqual
实例。然而,这是使用这种派生实例的特定方法的结果的约束。您始终可以自己提供它,然后即使对于泛型类,您也可能不需要 CanEqual
作为类型参数。例如。这似乎有效:
class C[T](t: T)
given CanEqual[C[_],C[_]] = CanEqual.derived
println(new C[Int](1) == new C[String]("1")) // false
正如我所说,这只是使用 ==
或 !=
的绿灯,它不会构造/派生比较操作本身。使用 equals()
方法,无论它的实现是什么。因此,对于您的案例,它将使用默认案例类 equals()
方法,并将使用 x
中函数的引用比较。
值得注意的是,scala.language.strictEquality
不限制使用 equals()
更多阅读: https://docs.scala-lang.org/scala3/book/ca-multiversal-equality.html https://dotty.epfl.ch/docs/reference/contextual/multiversal-equality.html 此外,我发现在“Scala 编程”和“Scala 编程”新版本中对此功能的描述更容易理解
希望对你有帮助