Scala,Java和平等

ach*_*erm 7 java scala equality reference file

val filesHere = (new java.io.File(".")).listFiles
val filesHere2 = (new java.io.File(".")).listFiles
Run Code Online (Sandbox Code Playgroud)

scala> filesHere == filesHere2
res0:Boolean = false

这非常直观.我宁愿期望filesHere和filesHere2相等.

这肯定是由于Java和Scala之间的语义不匹配,例如,关于数组或(文件)相等.显然,我在这里遗漏了一些东西!

Jon*_*han 17

如果我统治世界,我会弃用Scala的eq方法,因为名称与equals和== 极其混淆.相反,英语确实有表达身份,而不是平等的一句话:我会简单地把它称为.

同样地,我将取代Scala的NE(这是一个可怕的名字,因为它是两者的缩写,不知所云)与心不是.

在我看来,这些实际上可以添加到AnyRef并且旧方法已经弃用,即使在这个后期阶段也是如此.

  • 我非常喜欢这个想法. (3认同)
  • 是的,好主意,但"是"与类型检查是不明确的:obj是String,在其他语言中很流行,因此令人困惑. (3认同)

Tom*_*ett 8

equals()Java数组的方法使用引用相等而不是更复杂的东西,而Scala ==只是Java的equals().


soc*_*soc 8

比较无法按预期工作,因为此Java API返回一个数组.

Scala的数组和Java数组在幕后是相同的,虽然Scala的数组看起来像一个类,但它只是一个java.io.File [](在本例中).

这就是无法覆盖检查相等性的原因.Scala必须使用Java语义.

考虑这个例子:

val filesHere = (new java.io.File(".")).listFiles.toList
val filesHere2 = (new java.io.File(".")).listFiles.toList
Run Code Online (Sandbox Code Playgroud)

这将按预期工作.


Jam*_*ack 4

您可能想阅读这里:

\n\n

http://ofps.oreilly.com/titles/9780596155957/AdvancedObjectOrientedProgramming.html#EqualityOfObjects

\n\n

但看起来如果你这样做了:\nfilesHere.sameElements(filesHere2)那它应该是真的。

\n\n

该javadoc位于:\n http://www.scala-lang.org/api/2.6.0/scala/IterableProxy.html#sameElements%28Iterable%5BB%5D%29

\n\n

更新:

\n\n

第一个链接中的一些片段可能会有所帮助:

\n\n

在 Java、C++ 和 C# 中,== 运算符测试引用,而不是值相等。相反,Ruby\xe2\x80\x99s == 运算符测试值是否相等。无论您\xe2\x80\x99 使用什么语言,请务必记住,在 Scala 中,== 正在测试值是否相等。

\n\n

关于 ==在列表上未按预期工作:

\n\n

虽然这看起来似乎不一致,但鼓励对两个可变数据结构的相等性进行显式测试是语言设计者的保守方法。从长远来看,它应该可以避免您的条件出现意外结果。

\n\n

更新2:

\n\n

根据 Raphael 的评论,我查看了规范,最新更新的日期是两天前,我在http://www.scala-lang.org/files/archive/nightly/pdfs/ScalaReference上看到了这些.pdf

\n\n
Method equals: (Any)Boolean is structural equality, where two instances\nare equal if they both belong to the case class in question and they have equal\n(with respect to equals) constructor arguments.\n\nclass AnyRef extends Any {\n    def equals(that: Any): Boolean = this eq that\n    final def eq(that: AnyRef): Boolean = . . . // reference equality\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,Scala 2.10.2 中的定义似乎没有改变,因为规范似乎是一致的。如果行为不同,那么如果您编写单元测试,则应将其作为 Scala 的错误发送。

\n