Scala中的前向类引用?

Tim*_*rse 6 scala

作为Scala的新手,我遇到了一个标准问题:如何以这样的方式定义两个类,我可以创建一个另一个实例作为成员变量,然后又指向第一个实例?

我想最终得到一个Game实例,它有一个Dealer类型的成员,它有一个Game类型的成员,它实际上是原始的Game实例

因此,在这种情况下,每个实例(游戏,经销商)都有一个成员,这是另一个实例.任何人都可以指导我正确的方式吗?

Mor*_*itz 8

如果你真的需要使类不可变,你唯一的选择是在构造函数中使用name参数,并始终将实例创建为lazy vals:

class Dealer(val name: String, g: => Game) {
  lazy val game = g
  override def toString = "Dealer(name=%s, game=%s)".format(name, game.name)
}

class Game(val name: String, d: => Dealer) {
  lazy val dealer = d
  override def toString = "Game(name=%s, dealer=%s)".format(name, dealer.name)
}

lazy val game: Game = new Game("Doppelkopf", new Dealer("Peter", game))
lazy val dealer: Dealer = new Dealer("Tina", new Game("Poker", dealer))
Run Code Online (Sandbox Code Playgroud)

请注意,您需要在惰性val上使用类型ascription,否则它将无法编译.


oll*_*erg 2

我认为你正在谈论“双向”依赖关系,如果最多一个实体是不可变的,这很容易做到(如果你希望两者都是不可变的,你应该看到 Moviz 解决方案)。

在我的示例中,我让 theGame成为不可变的实体。荷官可能不参与游戏。

class Dealer(val name: String){
  var game: Option[Game] = None
}

case class Game(name: String, dealer: Dealer)

// Instanciate the game and the dealer
val olle = new Dealer("Olle")
val ollesGame = Game("Olles Game", olle)
olle.game = Some(ollesGame)
Run Code Online (Sandbox Code Playgroud)