scala - 相互引用的不可变实例

标签 scala

通过编写这些类(class),是否有任何可能的方法来创建一对男女朋友?也就是说,一个有女朋友的男孩,这个男孩也是她的男朋友。

abstract class Person(val name: String)

case class Girl(name2: String, val boyfriend: Boy) extends Person(name2)

case class Boy(name2: String, val girlfriend: Girl) extends Person(name2)


object Run extends App {
    val alice: Girl = Girl("alice", Boy("Bob",alice))

    // alice.boyfriend.girlfriend is null, not correct
}

最佳答案

如果没有惰性求值,就不可能创建自引用的不可变结构。然而,Scala 中的惰性求值(以惰性 val 和按名称调用的参数表示)并不像 Haskell 中那样普遍,而且它有其局限性。你的代码可以这样重写:

Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25).
Type in expressions to have them evaluated.
Type :help for more information.

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

abstract class Person(val name: String)

class Girl(val name2: String, _boyfriend: => Boy) extends Person(name2) {
    lazy val boyfriend = _boyfriend
}

class Boy(val name2: String, _girlfriend: => Girl) extends Person(name2) {
    lazy val girlfriend = _girlfriend
}


object Run {
    val alice: Girl = new Girl("alice", new Boy("Bob", alice))
}

// Exiting paste mode, now interpreting.

defined class Person
defined class Girl
defined class Boy
defined module Run

scala> Run.alice.name
res0: String = alice

scala> Run.alice.boyfriend.name
res1: String = Bob

scala> Run.alice.boyfriend.girlfriend.name
res2: String = alice

scala>

你看,这里没有案例类——你不能让案例类参数按名称调用,因为它们作为 val 公开,并且 val 具有按名称调用类型没有意义。此外,我还必须创建额外的惰性 val 字段,以便不会过早评估按名称调用的参数。

这段代码有可能可以简化,但它是实现你想要的我能想到的最简单的方法。

关于scala - 相互引用的不可变实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19534128/

相关文章:

scala - 从类名字符串中获取 TypeTag

Scala:检查空值/空值并返回 0 的简洁方法

scala - 在 Play Framework 2.5 的 scala twirl 模板中使用 isProd 和 isDev

android - 如何使用 Android 模块创建 sbt 项目并使用 Intellij Ultimate 运行?

scala - 根据特征中的抽象定义获取带有 val 的 null

java - Scala读取文件并拆分修改每一行

json - Play : validate JSON with a field with possible multiple types

scala - 如何在 scala.js 中使用 scala.sys.process

scala - 使用 Play 2.0 : exists but replace parameter is false 上传 Ajax 文件

scala - 使用 Scala 读取 Excel 文件