我不小心遇到了这样的情况(示例被简化以隔离问题):
abstract class Element(val other: Element)
case object First extends Element(Second)
case object Second extends Element(First)
object Main {
def main(arguments: Array[String]) {
val e1 = First
val e2 = Second
println("e1: "+e1+" e1.other: "+e1.other)
println("e2: "+e2+" e2.other: "+e2.other)
}
}
有人想猜测输出吗?:-)
e1: First e1.other: Second
e2: Second e2.other: null
输出有点意思。显然在创建第二个对象时,第一个对象尚不存在,因此null
已分配。问题是……大错特错!我花了几个小时才找到这个。编译器不应该告诉一些关于这个的事情吗?有趣的是,当我尝试将它作为 Scala 脚本运行时(相同的代码、减号object Main
和def main
行以及结束}
s),我得到了一个无限序列(不是真的无限 - 在某些时候列表停止,我猜是由于一些限制关于异常跟踪的深度,或类似这样的异常:
vilius@blackone:~$ scala 1.scala
...
at Main$$anon$1.Main$$anon$$Second(1.scala:4)
at Main$$anon$1$First$.<init>(1.scala:3)
at Main$$anon$1.Main$$anon$$First(1.scala:3)
at Main$$anon$1$Second$.<init>(1.scala:4)
at Main$$anon$1.Main$$anon$$Second(1.scala:4)
at Main$$anon$1$First$.<init>(1.scala:3)
...
我很想在运行时至少获得一些信息......
行。我吐槽完了。现在我想我应该问点什么。:) 那么,对于指向另一个的案例对象,您能推荐任何不错的设计吗?顺便说一句,在我的真实情况下,有几个对象以循环方式指向下一个和前一个实例(最后一个指向第一个,反之亦然)。
使用 Scala 2.8.1-final
编辑: 我找到了解决我的主要问题的方法:
abstract class Element {
val other: Element
}
case object First extends Element {
val other = Second
}
case object Second extends Element {
val other = First
}
这似乎在编译版本中工作(但不是作为 Scala 脚本!)。谁能解释一下这里发生了什么?
EDIT2:这作为一个脚本工作(同样的事情,只是使用def
s):
abstract class Element { def other: Element }
case object First extends Element { def other = Second }
case object Second extends Element { def other = First }