繁体   English   中英

如何在保留不变性的同时访问Scala中的复杂数据结构?

[英]how to access complex data structures in Scala while preserving immutability?

致电Scala专业开发人员! 假设您有一个代表可写数据存储的大对象。 您是否喜欢这种常见的类似Java的方法:

val complexModel = new ComplexModel()
complexModel.modify()
complexModel.access(...)

还是您更喜欢:

val newComplexModel = complexModel.withADifference
newComplexModel.access(...)

如果您愿意这样做,并且有一个客户端访问模型,那么客户端将如何知道指向newComplexModel而不是complexModel? 从用户的角度来看,您具有可变的数据存储。 您如何将这种观点与Scala对不变性的强调相协调?

这个怎么样:

var complexModel = new ComplexModel()
complexModel = complexModel.withADifference
complexModel.access(...)

这似乎有点类似于第一种方法,除了withADifference内部的代码似乎比Modify()内部的代码需要做更多的工作外,因为它必须创建一个全新的复杂数据对象而不是修改现有的对象。 您是否遇到了在保持不变性方面不得不做更多工作的问题?)而且,您现在拥有一个具有较大范围的var。

您将如何决定最佳策略? 您选择的策略是否有例外?

我认为功能性的方法是实际上使Stream包含您数据结构的所有不同版本,而使用者只是尝试从该流中提取下一个元素。

但是我认为在Scala中,这是绝对有效的方法,可在一个中心位置进行可变引用,并在您整个数据结构保持不变的情况下进行更改。

当数据结构变得更加复杂时,您可能会对以下问题感兴趣: 一种更清晰的方法来更新嵌套结构 ,该结构询问(并得到回答)如何实际创建不平凡的不可变数据结构的新更改版本。

对您问题的规范答案是使用Zipper ,这是一个有关SO的问题

我知道的唯一Scala实现是在ScalaZ中

通过仅modify方法的名称,很容易将您的ComplexModel识别为modify器对象,这意味着它会更改某些状态。 这仅意味着此类对象与函数式编程无关,并试图使其变得不可变,只是因为某个知识渊博的人告诉您,Scala中的所有内容都应当不可变,这只是一个错误。

现在您可以修改您的api,以便此ComplexModel对不可变数据进行操作,我想您应该这样做,但您绝对不能尝试将此ComplexModel转换为不可变本身。

不变性只是有用的工具,而不是教条。 出现不可变性的代价和不便超过其用途的情况。

ComplexModel的大小可能会使得在内存和/或CPU方面创建修改后的副本非常昂贵,因此可变模型更为实用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM