Я случайно столкнулся с такой ситуацией (пример упрощен, чтобы выделить проблему):
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)
...
Я бы хотел получить что-то хотя бы информативное во время выполнения ...
Ok. Я закончил свою напыщенную речь. Теперь, наверное, мне следует кое-что спросить. :)
Итак, не могли бы вы порекомендовать какой-нибудь красивый дизайн для объектов case, указывающих один на другой? Кстати, в моей реальной ситуации есть несколько объектов, указывающих на следующий и предыдущий экземпляры по кругу (последний указывает на первый и наоборот).
Использование Scala 2.8.1-final
EDIT:
Я нашел решение для моей основной проблемы:
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 }