【问题标题】:Case classes and Proxy behaviour in Scala 2.9Scala 2.9 中的案例类和代理行为
【发布时间】:2011-10-03 19:17:23
【问题描述】:

在将我们的代码迁移到 Scala 2.9 时,我们发现其中的大部分代码不起作用并且默默地失败了。我们将其追踪到扩展 Proxy 不相等的案例类。在我们的代码中,我们不直接扩展 Proxy,我们只是在扩展 Proxy 的库中扩展类。

任何帮助将不胜感激。

在 2.8 中

scala> case class Test(a:String) extends Proxy {
     |   def self = a
     | }
defined class Test

scala> 

scala> val label = new Test("bla")
label: Test = bla

scala> println(label == label) // this is TRUE
true

scala> println(label == "bla")
true

在 2.9 中

scala> case class Test(a:String) extends Proxy {
     |   def self = a
     | }
defined class Test

scala> 

scala> val label = new Test("bla")
label: Test = bla

scala> println(label == label) // this is now FALSE
false

scala> println(label == "bla")
true

更新

我认为这只能是 Scala 2.9 中的一个错误。否则,如果您有一个扩展任何其他类的案例类,您必须调查该基类的层次结构,以确保它绝不会扩展代理。我们将无法在我们的代码中执行此操作,我们将能够修复更明显的错误。如果这是预期的行为,那么编译器警告是必须的。听起来对吗?

更新

也在scala mailing list上讨论。

更新

我已经提交了bug

【问题讨论】:

  • 您最终是否将此报告为错误? (如果是这样,链接?) Proxy 的文档确实警告您它可能会导致 equals 不是对称的,但它没有警告您 equals 甚至可能不是自反的......!
  • Seth,我同意,这只能是一个错误。我已经更新了上面的链接。
  • 该错误报告已于 2011 年 9 月 10 日修复,仅供参考。
  • 是的,但在我庆祝之前,我正在等待它被分配到一个 Scala 版本。它已经修复了一段时间,但还没有发布的迹象。

标签: scala scala-2.8 case-class scala-2.9


【解决方案1】:

那么你为什么不覆盖equals方法呢?这应该可以解决问题。

【讨论】:

  • 通过使用案例类,您应该得到一个有效的 equals 方法。使用 case 类并覆盖 equals 方法似乎有点疯狂,我不能使用 case 类,这会起作用。只是我们的代码充满了它们。
  • 当然这并不理想,但我没有看到其他方法。
【解决方案2】:

在 2.9 中,他们将 equals 方法从:

override def equals(that: Any): Boolean = 
  if(that == null) false 
  else that equals self

override def equals(that: Any): Boolean = that match {
 case null       => false
 case x: Equals  => (x canEqual self) && (x equals self)
 case x          => (x equals self)
}

x:由于某种原因,Equals 不等于 self。

你可以重写equals方法来修复它。

【讨论】:

  • 我认为最简单的解决方法是将案例类更改为我们的类。然而,这似乎被打破了,或者至少应该记录在案的行为改变。谢谢
  • 我认为这可能是一个错误,但这个答案解释了错误的起源,所以我会接受它。谢谢乔。
【解决方案3】:

这会解决你的问题

case class Test(a: String) extends Proxy {
   def self = a
   def canEqual(that: Any) = that match {
      case that: String => true
      case _ => false
   }
}

【讨论】:

  • 或者,更简单地说,that.isInstanceOf[String]
  • 另外,请注意这意味着label == "blah" 将返回true
  • 根据问题中的结果在2.8中返回true。我认为其目的是复制 2.8 的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
相关资源
最近更新 更多