Elixir 是否具有类似于 Clojure 的持久数据结构?
Does Elixir have persistent data structures similar to Clojure?
Elixir 中的所有不可变数据结构都是持久化的吗?如果不是,它们中哪些是,哪些不是?另外,它们与 Clojure 中的持久数据结构相比如何?
是的,大部分都是持久化数据结构。
例如Elixir链表是链表,链表是退化树(只有一个分支):
Elixir: list = [1, 2, 3, 4]
Tree: 1 -> 2 -> 3 -> 4
每次您将一个元素添加到列表中时,它都会共享其尾部:
Elixir: [0|list]
Tree: 0 -> (1 -> 2 -> 3 -> 4)
Elixir 的 HashSet 和 HashDict 实现基于 Clojure 的持久数据结构,实际上是树。 There is some write up on Joseph's blog.
映射也是持久数据结构,它们非常有趣,因为它们的表示会根据键的数量而变化。当你有小地图时,假设:
%{:foo => 1, :bar => 2, :baz => 3}
表示为:
-------------(:foo, :bar, :baz)
|
(map, keys, values)
|
------(1, 2, 3)
因此,每次您更新一个键时,我们都会共享 "keys" 存储桶并且仅更改值存储桶。这对于小映射非常有效,但是一旦你达到大约 20 个键,在 Erlang 18 中,它们会将它们的表示更改为基于 Hash Array Mapped Tries,这也类似于 Clojure。
注意元组不是持久的(它们代表内存中的连续 space)。一旦更改元组中的一个元素,就会创建一个全新的元组。这使得它们非常适合保存和访问少量元素以及对它们进行模式匹配,但您绝对不想保存很多元素。
Elixir 中的所有不可变数据结构都是持久化的吗?如果不是,它们中哪些是,哪些不是?另外,它们与 Clojure 中的持久数据结构相比如何?
是的,大部分都是持久化数据结构。
例如Elixir链表是链表,链表是退化树(只有一个分支):
Elixir: list = [1, 2, 3, 4]
Tree: 1 -> 2 -> 3 -> 4
每次您将一个元素添加到列表中时,它都会共享其尾部:
Elixir: [0|list]
Tree: 0 -> (1 -> 2 -> 3 -> 4)
Elixir 的 HashSet 和 HashDict 实现基于 Clojure 的持久数据结构,实际上是树。 There is some write up on Joseph's blog.
映射也是持久数据结构,它们非常有趣,因为它们的表示会根据键的数量而变化。当你有小地图时,假设:
%{:foo => 1, :bar => 2, :baz => 3}
表示为:
-------------(:foo, :bar, :baz)
|
(map, keys, values)
|
------(1, 2, 3)
因此,每次您更新一个键时,我们都会共享 "keys" 存储桶并且仅更改值存储桶。这对于小映射非常有效,但是一旦你达到大约 20 个键,在 Erlang 18 中,它们会将它们的表示更改为基于 Hash Array Mapped Tries,这也类似于 Clojure。
注意元组不是持久的(它们代表内存中的连续 space)。一旦更改元组中的一个元素,就会创建一个全新的元组。这使得它们非常适合保存和访问少量元素以及对它们进行模式匹配,但您绝对不想保存很多元素。