如何初始化和“修改"程序. Scala中的循环持久数据结构? [英] How to initialize and "modify" a cyclic persistent data structure in Scala?

查看:78
本文介绍了如何初始化和“修改"程序. Scala中的循环持久数据结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经搜索并找到了有关此主题的一些信息,但是答案令人困惑或不适用.

I have searched and found some info on this topic but the answers are either confusing or not applicable.

我有这样的东西:

class Thing (val name:String, val refs:IndexedSeq[Ref])
class Ref (val name:String, val thing:Thing)

现在,我想说的是,加载文件,解析文件并从中填充此数据结构.它是不可变的且周期性的,怎么可能呢?

Now, I want to say, load in a file, parse it and populate this data structure from it. It being immutable and cyclic, how might one do so?

另外,假设我确实填充了此数据结构,现在我想对其进行修改,例如更改rootThing.refs(3).name,那怎么做?

Also, let's say I do get this data structure populated, now I want to modify it, like change rootThing.refs(3).name, how might one do that?

感谢这里发布的想法.在这一点上,我在想,如果真的想要类似这样的持久性数据结构,那就跳出框框思考一下,考虑一下客户端代码将要提出的问题.因此,不用考虑对象和字段,而要考虑查询,索引等.首先,我在考虑以下方面: 是否存在双向多图持久数据结构?

Thanks for the ideas posted here. At this point, I'm thinking that if one really wants persistent data structures for something like this, to think outside the box and consider what questions client code will need to ask. So instead of thinking of objects and fields, think of queries, indexes and such. To start with, I'm thinking in terms of: Is there a bidirectional multimap persistent data structure?

推荐答案

对于单个循环引用,可以使用lazy:

For a single cyclic reference, you can use lazy:

lazy val t: Thing = new Thing("thing", Vector(new Ref("ref", t)))

但是,显然,多对多连接使情况变得复杂.

However obviously this gets complicated with many-to-many connections.

我不知道是否存在通用的纯功能循环图数据结构.使用无环图,这很容易,因为您可以对其进行拓扑排序,然后逐步对其进行初始化.

I don't know if a general purpose purely functional cyclic graph data structure exists. With acyclic graphs this would be easy as you could topologically sort it and then initialize it step by step.

也许您可以选择使用间接寻址,比如说通过标识符而不是实际的scala对象引用来引用对象?

Maybe using an indirection is an option for you, say to refer to objects through an identifier instead of the actual scala object reference?

case class ThingByID(id: Int, name: String, refs: IndexedSeq[RefByID])
case class RefByID(name: String, thingID: Int)

然后,在加载文件后,您可以通过ID将事物收集到不可变的映射中(例如collection.immutable.IntMap),并在从引用中获取时进行查找.

Then you could after loading your file collect the things by their ID into an immutable map (e.g. collection.immutable.IntMap) and look them up when coming from a ref.

编辑

Miles是正确的.确实,您需要像他的答案一样使用名字参数.

Miles is right about the first case of the lazy val t. Indeed you need by-name parameters as in his answer.

class Thing(val name: String, val refs: IndexedSeq[Ref])
class Ref(val name: String, _thing: => Thing) { def thing = _thing }

val t: Thing = new Thing("thing", Vector(new Ref("ref", t)))

这篇关于如何初始化和“修改"程序. Scala中的循环持久数据结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆