我无意中遇到了这样的情况(为了隔离问题,以下示例进行了简化):
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
行以及关闭的}
),我得到了一个无限序列(实际上不是无限的——在某个点上列表停止了,我猜测是由于异常跟踪深度的某些限制或其他原因)像这样的异常: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脚本!)。有人可以解释一下发生了什么吗?
编辑2: 这个脚本有效(相同的内容,只是使用了def
):
abstract class Element { def other: Element }
case object First extends Element { def other = Second }
case object Second extends Element { def other = First }