Scala 3 隐式转换:比较值和文字
Scala 3 implicit conversions: compare value and literal
我有一个不透明类型 FancyDouble
,它是通过在伴随对象范围内使用 given Conversion[Double, FancyDouble] = FancyDouble(_)
从 Double 隐式转换而来的。在那之后,构造 val d: FancyDouble = 0.0
起作用了,但是当我尝试像 if (d == 0.0)
那样进行比较时,编译器抱怨我无法比较 FanceDouble
和 Double
(我我期待它应该隐式地将 0.0
文字转换为 FancyDouble,就像在前面的例子中一样。
如何启用隐式转换比较?
平等本质上定义为(Any, Any) => Boolean
。主要是因为 Java 遗产。这意味着在 fancyDouble == double
中,预期的表达式类型 double
是 Any
并且不会触发任何隐式转换。
但是 Scala 3 introduced CanEqual
类型类使平等更安全一些。如果要比较类型 A
和 B
的值,CanEqual[A, B]
的隐式实例需要在隐式范围内。
object fancy {
opaque type FancyDouble = Double
def make(d: Double): FancyDouble = d
given CanEqual[FancyDouble, Double] = CanEqual.derived
given CanEqual[Double, FancyDouble] = CanEqual.derived
}
val a = 4.2
val b = fancy.make(4.2)
assert(a == b) // ok
assert(b == a) // ok
如果启用 strictEquality
标志,您甚至需要一个 CanEqual[FancyDouble, FancyDouble]
来比较两个 FancyDouble
。
我有一个不透明类型 FancyDouble
,它是通过在伴随对象范围内使用 given Conversion[Double, FancyDouble] = FancyDouble(_)
从 Double 隐式转换而来的。在那之后,构造 val d: FancyDouble = 0.0
起作用了,但是当我尝试像 if (d == 0.0)
那样进行比较时,编译器抱怨我无法比较 FanceDouble
和 Double
(我我期待它应该隐式地将 0.0
文字转换为 FancyDouble,就像在前面的例子中一样。
如何启用隐式转换比较?
平等本质上定义为(Any, Any) => Boolean
。主要是因为 Java 遗产。这意味着在 fancyDouble == double
中,预期的表达式类型 double
是 Any
并且不会触发任何隐式转换。
但是 Scala 3 introduced CanEqual
类型类使平等更安全一些。如果要比较类型 A
和 B
的值,CanEqual[A, B]
的隐式实例需要在隐式范围内。
object fancy {
opaque type FancyDouble = Double
def make(d: Double): FancyDouble = d
given CanEqual[FancyDouble, Double] = CanEqual.derived
given CanEqual[Double, FancyDouble] = CanEqual.derived
}
val a = 4.2
val b = fancy.make(4.2)
assert(a == b) // ok
assert(b == a) // ok
如果启用 strictEquality
标志,您甚至需要一个 CanEqual[FancyDouble, FancyDouble]
来比较两个 FancyDouble
。