派生 `CanEqual` 在函数上不应该成功

问题描述

我是 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 编程”新版本中对此功能的描述更容易理解

希望对你有帮助