我有一组复杂的特征和案例类,但是出于讨论的目的,让我总结一下我要以此方式建模的内容:
case class X(x: X)
这很好,直到我最终以这种方式初始化实例之一:
val myX: X = X(myX)
它会编译(令人难以置信),但是传递给构造函数的myX
实际上是 null ,随后检查myX.x
可以很容易地看到它。
假设有一个指向自身的实例适合我要建模的对象,是否有一种优雅的方法来解决此问题,并使X
的新实例具有指向自身的指针?我的意思是在创建对象后不对其进行更改,也无需引入不带参数且内部使用this
的第二个构造函数。请记住,请记住,实际情况要比此处描绘的复杂得多。
答案 0 :(得分:6)
如果您需要一个案例课,我认为这是不可能的。案例类不能具有惰性参数,如果它们可以指向自己,则大多数方法可能会破坏堆栈。通过常规课程,您可以执行以下操作:
scala> class X(x0: =>X) {
| lazy val x = x0
| }
class X
scala> val x: X = new X(x)
val x: X = X@5f98cb6f
scala> x.x
val res0: X = X@5f98cb6f
scala> x.x.x
val res1: X = X@5f98cb6f
如果您想要类似案例类的行为,则必须自己实现样板(应用,取消应用,复制,等于,哈希码等),并且要非常小心,不要触发无限循环或堆栈溢出
答案 1 :(得分:2)
不明智的做法是,在这种情况下考虑考虑“模拟”按名称参数
case class X(v: () => X) {
def x: X = v.apply
}
val myX: X = X(() => myX)
但是请注意Jasper-M的警告。