【发布时间】:2025-12-08 17:05:02
【问题描述】:
我正在尝试在 Scala 中使用 来模拟 !=。
implicit def conditional[A](left : A) = new {
| def<>[A](right : A) = (left != right)
| }
什么情况下这个模拟不起作用
【问题讨论】:
我正在尝试在 Scala 中使用 来模拟 !=。
implicit def conditional[A](left : A) = new {
| def<>[A](right : A) = (left != right)
| }
什么情况下这个模拟不起作用
【问题讨论】:
这应该总是有效的,但可能不是你想象的那样。你认为这两种类型是相同的吗?如果是的话,应该是
class Conditionalize[A](left: A) { def <>(right: A) = left != right }
implicit def conditional[A](left: A) = new Conditionalize(left)
如果没有,使用单独的类型参数会更清楚:
implicit def notequality[A](a: A) = new { def <>[B](b: B) = a != b }
仅当 LHS 不需要隐式转换为与 RHS 相同的类型时,前者才有效。定义有条件但未定义音符质量:
implicit def int_to_string(i: Int) = i.toString
scala> "5" <> 5
res0: Boolean = false
scala> 5 <> "5"
<console>:9: error: type mismatch;
found : java.lang.String("5")
required: Int
5 <> "5"
因为你不能链接隐式。
后一种情况将像 != 一样工作。 (编辑:关于null 值的一种特殊情况,由于其类型为Null。)
这两个都将包裹原语,这将使其在繁重的工作中变慢。但是 Scala 避免了 Java 中 0.0 == -0.0 但 (new java.lang.Double(0.0)).equals(new java.lang.Double(-0.0)) 为假的怪异之处,因此您不应该注意到结果的差异。
如果您愿意,可以添加 @specialized 以使比较器避免装箱原语,但会增加代码大小。
【讨论】:
需要注意的一点是<> 的优先级与== 不同,所以如果没有括号,有些事情将无法工作。例如:
a <> b >> 2 // (a <> b) >> 2
a != b >> 2 // a != (b >> 2)
【讨论】:
< 和> 的优先级相同。