Elixir 是不是具有类似于 Clojure 的持久数据结构?

Posted

技术标签:

【中文标题】Elixir 是不是具有类似于 Clojure 的持久数据结构?【英文标题】:Does Elixir have persistent data structures similar to Clojure?Elixir 是否具有类似于 Clojure 的持久数据结构? 【发布时间】:2015-05-12 23:38:23 【问题描述】:

Elixir 中的所有不可变数据结构都是持久的吗?如果不是,它们中的哪些是,哪些不是?另外,它们与 Clojure 中的持久数据结构相比如何?

【问题讨论】:

你的意思是这样的,对吧? hypirion.com/musings/understanding-persistent-vector-pt-1 【参考方案1】:

是的,其中大部分是持久性数据结构。

例如,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)

因此,每次您更新一个键时,我们都会共享“键”存储桶并仅更改值存储桶。这对于小型映射非常有效,但是一旦在 Erlang 18 中达到大约 20 个键,它们就会将其表示更改为基于 Hash Array Mapped Tries,这也类似于 Clojure。

注意元组不是持久的(它们代表内存中的连续空间)。一旦更改元组中的一个元素,就会创建一个全新的元组。这使得它们非常适合保存和访问少量元素以及对它们进行模式匹配,但您绝对不想保存很多元素。

【讨论】:

谢谢!所以主要的区别是没有持久的向量/元组。有没有长生不老药清单的属性的书面记录?是 O(1) 吗?追加到结尾? 在这里找到答案,长度是O(n),附加到end也是O(n)。有实现持久向量的计划吗? 目前您有两种选择:使用 Erlang 的“数组”模块或使用地图作为向量(键是数字)。但是,如果您想做非常具体的向量操作,第二个选项就不够了。我们已经讨论过添加向量,但目前不在路线图中。 Aja 库(完全公开:我是作者)实现了基于 Clojure 设计的持久向量。它仍处于早期阶段,但旨在提供有吸引力的第三种选择。

以上是关于Elixir 是不是具有类似于 Clojure 的持久数据结构?的主要内容,如果未能解决你的问题,请参考以下文章

Elixir/Erlang 中的命名函数是不是有等效于 __MODULE__ 的方法?

为啥没有窥视! clojure 瞬态向量的函数?

如何在 Windows 中拥有最新版本的 Elixir

Clojure - recur 适用于循环或 let 语句?

Ruby 中类似 Elixir 的管道来处理集合

Elixir - 在监督下启动 Java JInterface OTP 节点