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

发布于 2024-10-14 21:59:32 字数 367 浏览 4 评论 0原文

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

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

但实际上必须有编译器魔法来避免空指针异常,对吧?有什么方法可以让我用纯 Scala 复制这种行为吗?即,如果接收者为空,则让运算符/方法返回一件事,如果不是,则返回另一件事?我的意思是 null eq this 的实际实现。

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

In Programming in Scala, I can read that the == operator behaves as if it was defined like this:

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

But there must actually be compiler magic to avoid null pointer exceptions, right? Is there any way for me to replicate this behavior with pure Scala; i.e., have an operator/method return one thing if the receiver is null and another one if it isn't? What I mean is an actual implementation of null eq this.

I suppose I can write a "pimp" and then define the method on the wrapper class, but is there a more direct way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

自此以后,行同陌路 2024-10-21 21:59:32

我不这么认为。 据我所知,空值没有魔法。(请参阅更新)

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

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

根据它:

Null 类与 Nothing 类一起位于 Scala 类型层次结构的底部。

因此,即使 null 也有从 AnyRef 继承的方法,例如 eq== 等......而且您也可以使用它们:

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

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

I don't think so. As far as I know there is no magic for nulls. (see Update)

I think the best you can do, is to wrap any object to option, so that you can use bunch of useful stuff from it:

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

Update

I found this document:

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

According to it:

Class Null is - together with class Nothing - at the bottom of the Scala type hierarchy.

So even null has methods inherited from AnyRef like eq, ==, etc... And you also can use them:

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

println(null eq q) // prints: true
println(null eq q1) // prints: false
假面具 2024-10-21 21:59:32

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

您绝对应该检查 Option 并尽一切努力将 null 排除在代码之外:)

"null" is the only instance of a trait called Null - so it's just a normal object, no magic to invoke ==

You should definitely check out Option and do everything you can to keep nulls out of your code :)

汹涌人海 2024-10-21 21:59:32

如果不对 null 情况进行特殊处理,似乎没有任何方法可以做到这一点。如果对象为 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"

There doesn't appear to be any way to do this without special casing the null case. Java won't allow a method to be called if the object is null. This compared to a language like python where None is a proper object. I think the best thing to do is try and ignore the fact that null exists.

Useing an implicit to simulate ==

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) 

Unfortunately the following doesn't work as null is not a subclass of AnyRef

null === "Something"
眼前雾蒙蒙 2024-10-21 21:59:32

null 没有什么魔力,但 scala 确实有一些魔力可以让数字相等对称。
诀窍是扩展 ScalaNumber 特征...

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

update

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

这不仅解决了 null 情况,而且如果您想要将基元与可以被视为数字的其他类型进行比较,但对于隐式转换会导致这种情况,它也会使事情变得容易得多。鲁莽地不安全。这是 BigInteger 等使用的方法。

There's no magic for nulls, but scala does have some magic for making equality symmetric for numbers.
The trick is to extend the ScalaNumber trait...

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

update

Just to clarify that a bit... This means that if you write a == b and b derives from ScalaNumber or (I believe) is an AnyVal, then the compiler will test instead for b == a.

Not only does this resolve the null situation, but it also makes things a lot easier if you want to compare a primitive to some other type that can be viewed as a number, but for which an implicit conversion would be recklessly unsafe. This is the approach used with e.g. BigInteger.

国际总奸 2024-10-21 21:59:32

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

如果您按照上面在类 A 中发布的精神定义函数,那么您所要做的就是提供从 NullA 的隐式转换code> 将 null 映射到某个虚拟实例。

null is the only instance of Null and is therefore -- in Scala -- a full object.

If you define your function in the spirit as you posted above in class A, all you have to do is to provide an implicit conversion from Null to A that maps null to some dummy instance.

那请放手 2024-10-21 21:59:32

您可以使用选项。

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

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

You can use Option.

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

scala> Option(null)
res1: Option[Null] = None
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文