我试图将 Java 中的一个片段翻译成 Scala。
它是一个无限的树结构。

class Node {
    public Node(Map<String, Node> routes) {}
}

class Factory {
    public Map<String, Node> buildRoutes() {
        Map<String, Node> routes = new HashMap<>();
        asList("one", "two").forEach(key -> routes.put(key, new Node(routes));
        return routes;
    }

它工作得很好。一旦我将上面的片段翻译成 Scala,我就注意到 Map 的一个问题。看起来在 Scala 股票中可变和不可变映射不兼容。

所以我必须在 Node.js 字段中使用可变映射类型。
至于我,它看起来很奇怪,因为我的 map 不可变。
它在 Node 中没有改变,Node 必须稍微了解它应该的依赖关系。
import scala.collection.mutable

case class Node(routes: mutable.Map[String, Node])

object Factory {
   def buildRoutes(): mutable.Map[String, Node] = {
      val routes = new mutable.HashMap[String, Node]
      List("one", "two").foreach(key => routes.put(key, Node(routes)))
      routes
   }
}


我很高兴看到一个替代解决方案,其中 Node.routes 是一个不可变的 map 。

最佳答案

这里没有什么是可变的:

class Node(unfold: => Map[String, Node]) {
  def routes: Map[String, Node] = unfold
}

object Factory {
   def buildRoutes: Map[String, Node] = {
      def fix: Map[String, Node] =
        List("one", "two").map(_ -> new Node(fix)).toMap
      fix
   }
}

它在没有 StackOverflowError 的情况下构建,并且仍然可以无限展开:
val rs = Factory.buildRoutes
println(rs("one").routes("one").routes("two").routes("one").routes.keys)

关键是作用域中的函数定义可以递归地引用它们自己。

关于scala - 如何在scala中构建无限不可变树,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57775623/

10-15 08:40