我正在努力理解Elixir
中列表和元组之间的区别。从Elixir指南的Basic Types部分,我理解:
好的,这一切都很好但我还不确定时要使用什么。我看到大多数方法返回一个元组但是其他地方都使用了Lists,并且许多方法接受Lists作为输入,而不是元组。根据上面提到的观点,不应该使用元组来传递数据,因为从用户给定值的元组读取会很快吗?
我也注意到元组不是可枚举的,那是什么?不会在{1}上使用Enum
比在列表中使用它更快吗?
如果有人可以帮助我更好地理解它们,可能只是举几个例子说明什么时候使用,那就太棒了。
答案 0 :(得分:36)
你已经对这些差异给出了很好的总结,所以在其中一件事情很重要的任何条件下,它都应该帮助你决定使用哪些。
考虑它的方法是列表是开放式数据结构,它们的大小可以在运行时变化,而元组在编译时设置了恒定的大小。
例如,如果您想要存储用户在iex
会话期间提供的所有命令,您需要一个列表 - 该列表的长度将取决于该会话中给出的命令数。将其与元组的典型用例进行对比 - 从方法中返回{:ok, result}
或{:error, reason}
- 此处元素的数量是预先知道的,因此您不会为性能付出不可接受的代价元组的改进。
至于枚举 - 元组概念上不是集合,每个元素的位置也应该表示它的作用。考虑一个{:ok, #PID<0.336.0>}
元组 - 迭代它会首先给你一个:ok
然后一个#PID<0.336.0>
,编写一个以统一的方式对这些东西起作用的函数会很奇怪。 / p>
答案 1 :(得分:18)
我不是专家,但这是我的理解:
在幕后,列表是一个链表。因此它具有链表的性能特征。也就是说,获取长度是O(n)因为我必须遍历整个列表。同样,列表也具有链表的优点;也就是说,通过添加到前面来增加它很容易。
我不确定幕后是什么元组,但我知道它不是一个链表。有人问到2013年在Elixir语言邮件列表上列举了元组,这是回复的一部分:
“元组也不应该被迭代,不要被混淆 事实上你可以使用elem / 2和size / 1。元组是为了 将多条信息存储在一起,这并不意味着 它们用于存储集合。“
- Peter Minten
“另一种解释是,元组是穷人的记录 换句话说,元组代表单个数据,单个数据 价值,虽然是汇总。你不能从元组中夺走一个元素 而不改变该特定元组值的语义含义。
“这与存储许多内容的列表和其他集合相反 重视独立价值观。简单地从列表中取出一个值 减少列表的长度。它不会影响语义 任何东西。“
- Alexei Sholik
换句话说,仅仅因为元组和列表之间存在肤浅的相似性,就不应该假设行为是相同的。
答案 2 :(得分:12)
除了已经说过的内容之外,帮助我区分元组和列表的内容类似于数据库中的一行。如果你以这种方式考虑元组,很容易看出元组中的信息是如何相互关联的,并且很明显为什么你不会将它用作Enumerable。
答案 3 :(得分:1)
如果您熟悉Java:
LinkedList
。ArrayList
。答案 4 :(得分:0)
由于有人提到他们不确定元组在引擎盖下是什么类型,因此元组与数组类似,因为数组和元组都将元素存储在连续的内存中。因此,当您在链接列表上使用数组时,将遵循相同的规则,就像使用Elixir中的列表上的元组一样。
答案 5 :(得分:0)
Tuples旨在容纳固定数量的元素,这就是为什么它们预先分配内存的原因。基本上,元组不是要更改的(尽管有可能,但代价昂贵)。它们提供了一条相关信息。
例如:地理坐标{43.258389,-2.924405}
相反,列表更适合动态集合(修改起来更便宜)。
我发现这篇文章非常有用:https://blog.appsignal.com/2018/08/21/elixir-alchemy-list-vs-tuples.html