将要构造的实例传递给case类构造函数

时间:2020-02-06 12:31:07

标签: scala

我有一组复杂的特征和案例类,但是出于讨论的目的,让我总结一下我要以此方式建模的内容:

case class X(x: X)

这很好,直到我最终以这种方式初始化实例之一:

val myX: X = X(myX)

它会编译(令人难以置信),但是传递给构造函数的myX实际上是 null ,随后检查myX.x可以很容易地看到它。

假设有一个指向自身的实例适合我要建模的对象,是否有一种优雅的方法来解决此问题,并使X的新实例具有指向自身的指针?我的意思是在创建对象后不对其进行更改,也无需引入不带参数且内部使用this的第二个构造函数。请记住,请记住,实际情况要比此处描绘的复杂得多。

2 个答案:

答案 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的警告。