【问题标题】:Emulating != in scala using <>使用 <> 在 scala 中模拟 !=
【发布时间】:2025-12-08 17:05:02
【问题描述】:

我正在尝试在 Scala 中使用 来模拟 !=。

implicit def conditional[A](left : A) = new {
 |   def<>[A](right : A) = (left != right)
 | }

什么情况下这个模拟不起作用

【问题讨论】:

    标签: scala emulation


    【解决方案1】:

    这应该总是有效的,但可能不是你想象的那样。你认为这两种类型是相同的吗?如果是的话,应该是

    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 以使比较器避免装箱原语,但会增加代码大小。

    【讨论】:

      【解决方案2】:

      需要注意的一点是&lt;&gt; 的优先级与== 不同,所以如果没有括号,有些事情将无法工作。例如:

      a <> b >> 2  // (a <> b) >> 2
      a != b >> 2  // a != (b >> 2)
      

      【讨论】:

      • 是的,但不是一个严重的问题,因为&lt;&gt; 的优先级相同。
      • @Rex 我不同意。对我来说,平等与秩序不同。