Clojure 有一个非常好的概念 transient collections .是否有提供 Scala(或 F#)的库?
最佳答案
对于像 F# 这样的语言来说,这听起来是一个非常棒的概念,感谢您提供有趣的链接!
使用数组进行编程时,F# 程序员使用完全相同的模式。例如,创建一个可变数组,命令式地初始化它,返回它,然后使用将它视为不可变的函数来处理它,例如 Array.map
(即使数组实际上可以突变,因为没有 transient 数组)。
使用 seq<'a> 类型:做类似事情的一种方法是将数据结构转换为通用序列( seq<'a>
),它是一种不可变的数据类型,因此您不能(直接)通过 seq<'a>
修改原始数据结构.例如:
let test () =
let arr = Array.create 10 0
for i in 0 .. (arr.Length - 1) do
arr.[i] <- // some calculation
Array.toSeq arr
好消息是转换通常是 O(1)(数组/列表/.. 实现
seq<'a>
作为接口(interface),所以这只是强制转换)。但是,seq<'a>
不保留源集合的属性(例如效率等),您只能使用处理序列的通用函数(来自 Seq
模块)来处理它。但是,我认为这相对接近 transient 集合模式。类似的.NET类型也是
ReadOnlyCollection<'a>
它将集合类型(比 seq<'a>
更强大)包装到一个不可变的包装器中,该包装器用于修改集合的操作抛出异常。相关类型:对于更复杂的集合类型,F#/.NET 通常同时具有可变和不可变实现(来自 F# 库的不可变实现)。这些类型通常完全不同,但有时共享一个通用接口(interface)。这使得在您使用突变时可以使用一种类型,并在您知道不再需要它时将其转换为另一种类型。但是,这里您需要在不同结构之间复制数据,因此转换绝对不是 O(1)。它可能介于 O(n) 和 O(n*log n) 之间。
类似集合的示例是可变的
Dictionary<'Key, 'Value>
不可变 Map<'Key, 'Value>
和可变的HashSet<'T>
或 SortedSet<'T>
不可变 set<'T>
(来自 F# 库)。
关于scala - Scala 的 transient 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2573966/