1

假设我有两个数据结构都想要引用另一个。我不能简单地让每个人都成为懒惰的 val,然后将它们相互传递;发生堆栈溢出。

我想出的解决方案是这样的:

class Alpha((deferredBeta: Alpha) => Beta) {
   lazy val beta = deferredBeta(this)
}

class Beta(val alpha: Alpha) {}

def main {
   val alpha = Alpha(beta)
   val beta = (alpha: Alpha) => Beta(alpha)
}

虽然它有效,但它似乎有点脆弱,特别是在子类化方面。此外,如果没有良好的文档,所做的事情并不明显。

这个问题有更清洁的解决方案吗?

4

2 回答 2

3

I think this solution is the simplest:

class Alpha(_beta: => Beta) {
  lazy val beta = _beta
}

class Beta(_alpha: => Alpha) {
  lazy val alpha = _alpha
}

// Exiting paste mode, now interpreting.

defined class Alpha
defined class Beta

scala> lazy val (alpha: Alpha, beta: Beta) = (new Alpha(beta), new Beta(alpha))
alpha: Alpha = <lazy>
beta: Beta = <lazy>

scala> alpha.beta
res2: Beta = Beta@4a40050

scala> beta.alpha
res3: Alpha = Alpha@38f18cc3

You could also add a factory for an alpha beta pair:

object AlphaBeta {
  def apply() = {
    lazy val tuple @ (alpha: Alpha, beta: Beta) = (new Alpha(beta), new Beta(alpha))
    tuple
  }
}

scala> AlphaBeta()
res13: (Alpha, Beta) = (Alpha@2a3fa87a,Beta@394df741)
于 2012-08-06T11:11:57.930 回答
1

不完全符合您的要求,但它有效:

scala> :paste
// Entering paste mode (ctrl-D to finish)

trait Alpha {
  self: Beta =>
  val beta: Beta = self
}

trait Beta {
  self: Alpha =>
  val alpha: Alpha = self
}

// Exiting paste mode, now interpreting.

defined trait Alpha
defined trait Beta

scala> val (alpha, beta) = {
     |   val ab = new Alpha with Beta
     |   (ab: Alpha, ab: Beta)
     | }
alpha: Alpha = $anon$1@13668e0b
beta: Beta = $anon$1@13668e0b

scala> alpha.beta
res0: Beta = $anon$1@13668e0b
于 2012-08-06T10:57:00.177 回答