Scala 如何使用不变的设计跟踪依赖关系?

Scala 如何使用不变的设计跟踪依赖关系?,scala,functional-programming,immutability,Scala,Functional Programming,Immutability,当对象之间存在依赖关系时,以功能方式设计软件的方法是什么 class Link(val name: String, val links: Vector[Link] = Vector()){ def changeName(newName: String): Link = { new Link(newName, links) } def connect(other: Link): Link = { new Link(name, links

当对象之间存在依赖关系时,以功能方式设计软件的方法是什么

class Link(val name: String, val links: Vector[Link] = Vector()){

    def changeName(newName: String): Link = {
        new Link(newName, links)
    }

    def connect(other: Link): Link = {
        new Link(name, links :+ other)
    }
}

object Main
{
    def main(args: Array[String]): Unit = {
            val A = new Link("A")
            val B = new Link("B")
            val Alinked = A connect B 
            val updatedB = B changeName "B2"
            println(Alinked.links.contains(updatedB))
    }
}
输出

假的

我连接了A和B,但是B被改变了。这意味着,我必须将新对象重新连接到以前的对象。在复杂的层次结构中,控制这样的更新非常困难


如何进行自动重新链接?代表?参与者?

如果需要将对象的不可变副本的标识保存在一起,我认为一种解决方案是引入唯一标识符:

case class Link(id: Int)(val name: String, val links: Vector[Link] = Vector()) {
  def changeName(newName: String): Link =
    new Link(id)(newName, links)

  def connect(other: Link): Link =
    new Link(id)(name, links :+ other)
}

def test(): Boolean = {
  val A         = Link(0)("A")
  val B         = Link(1)("B")
  val Alinked   = A connect B 
  val updatedB  = B changeName "B2"
  Alinked.links.contains(updatedB)
}

assert(test())

也就是说,一旦创建了一个对象,您就可以在所有副本中携带相同的
id
。这里的
case类
通过查看
id
字段来确保
等于
的定义是正确的。

因此基本上没有办法重新创建指针并将当前状态保持在
映射[id,Any]
?您可以使用双向链接,然后,
connect
必须同时更新接收器和源。但是,是的,每个步骤都需要一份状态副本。如果您想要一种不可变但并发安全的更简单方法,我建议使用STM(软件事务内存)。有一个很好的图书馆供你阅读Scala@0__有没有一种方法可以让静态指针始终指向类的最后一个实体?@CronAcronis没有,因为这样你基本上回到了可变设计,只是更加复杂。我认为双向图和相互依赖性本质上很难以不变的方式维护。如果您的代码从不并发运行,那么最好使用可变结构。正如我所说的,我们也来看看STM。还有