我可以为==重现Scala的行为吗?

时间:2011-01-31 18:26:31

标签: scala null equals

在Scala中的编程中,我可以读到==运算符的行为就好像它是这样定义的:

final def == (that: Any): Boolean = if (null eq this) {null eq that} else {this equals that}

但实际上必须有编译魔术才能避免空指针异常,对吧?有没有办法让我用纯Scala复制这种行为;即,如果接收方为空,有一个操作符/方法返回一个东西,如果不是,则返回另一个东西?我的意思是null eq this的实际实现。

我想我可以编写一个“pimp”,然后在包装类上定义方法,但是有更直接的方法吗?

6 个答案:

答案 0 :(得分:2)

我不这么认为。 据我所知,空值没有魔力。(见更新)

我认为你能做的最好的事情是将任何对象包装成选项,这样你就可以使用它中的一堆有用的东西:

implicit def toOption[T](target: T) = Option(target)

val q: String = null
val q1: String = "string"

println(q getOrElse "null") // prints: null
println(q1  getOrElse "null") // prints: string

更新

我找到了这个文件:

http://www.scala-lang.org/api/2.7.7/scala/Null.html

根据它:

  

Class Null与Scalle类型层次结构底部的Nothing一起。

所以即使null还有AnyRef继承的方法,例如eq==等等,您也可以使用它们:

val q: String = null
val q1: String = "string"

println(null eq q) // prints: true
println(null eq q1) // prints: false

答案 1 :(得分:2)

“null”是一个名为Null的特征的唯一实例 - 所以它只是一个普通的对象,没有魔法可以调用==

你绝对应该检查Option并尽一切可能保持代码中的空值:)

答案 2 :(得分:2)

对于空值没有什么神奇之处,但是scala确实有一些魔法,可以使数字的等式对称。 诀窍是扩展ScalaNumber特征......

http://www.scala-lang.org/node/6387

<强>更新

只是为了澄清一点......这意味着如果你写a == bb来自ScalaNumber或(我相信)是AnyVal,那么编译器将测试b == a

这不仅可以解决null情况,而且如果你想将一个原语与一些可以被视为数字的其他类型进行比较,它也会使事情变得容易得多,但是隐含的转换会肆无忌惮地不安全。这是与例如使用的方法。的BigInteger。

答案 3 :(得分:2)

如果没有特殊的空壳情况,似乎没有办法做到这一点。如果对象为null,Java将不允许调用方法。这与像python这样的语言相比,其中None是一个合适的对象。我认为最好的办法是尝试忽略null存在的事实。

使用隐式模拟==

class Equals2(v:AnyRef){
  def ===(that:AnyRef) =  if(v eq null) {that eq null }else {v equals that}
}
implicit def equals2(v:AnyRef) = new Equals2(v) 

不幸的是,以下内容不起作用,因为null不是AnyRef的子类

null === "Something"

答案 4 :(得分:1)

nullNull的唯一实例,因此在Scala中是一个完整的对象。

如果您按照上面在课程A中发布的精神定义了您的功能,那么您所要做的就是提供从NullA的隐式转换,映射{{ 1}}到一些虚拟实例。

答案 5 :(得分:0)

您可以使用选项。

scala> Option("a")
res0: Option[java.lang.String] = Some(a)

scala> Option(null)
res1: Option[Null] = None