Определить рекурсивные ссылки - отложенный вызов вызывает переполнение стека
Для сценария потока данных мне нужны значения, которые рекурсивно ссылаются друг на друга. Следующее не работает:
class Foo(val that: Foo)
class Bar {
lazy val a: Foo = new Foo(b)
lazy val b: Foo = new Foo(a)
println(s"a = $a, b = $b")
}
new Bar // boom!
Как бы я решить это, не пачкая руки var
?
2 ответа
Решение
Вам просто нужно больше ленивых!
class Foo(_that: => Foo){ lazy val that = _that }
class Bar {
lazy val a: Foo = new Foo(b)
lazy val b: Foo = new Foo(a)
println(s"a = $a, b = $b")
}
val bar = new Bar
bar.b.that eq bar.a
// true
bar.b eq bar.a.that
// true
Вы можете использовать параметр по имени и другой lazy val
:
class Foo(_that: => Foo) {
lazy val that = _that
}
class Bar {
lazy val a: Foo = new Foo(b)
lazy val b: Foo = new Foo(a)
println(s"a = $a, b = $b")
}
val bar = new Bar()
println(bar.a.that)
Параметр by name откладывает оценку ссылки на другой Foo
, Как только вы получите доступ that
, и то и другое Foo
s были созданы, так что вы в порядке.