列表与元组 – 什么使用和什么时候?

我正在努力把握Elixir 列表元组之间的区别。 从Elixir指南的基本types部分,我明白:

  • 列表存储为链接的项目
  • 更新一个列表是快速的(只有当预先计划)
  • 提取列表项目很慢
  • 提取列表信息(大小/长度)很慢
  • 元组元素存储在一起
  • 获取元组信息是快速的
  • 获取Tuple元素是快速的
  • 修改元组是昂贵的

好吧,这一切都很好,但我仍然不知道什么时候使用 。 我发现大多数方法返回一个元组,但是在其他地方使用了列表,许多方法接受列表作为input,而不是元组。 通过上面所述,不应该使用元组来传递数据,因为从用户给定值的元组中读取会很快?

我也注意到元组不是可枚举的,怎么了? 不会使用Enum在它们上比在列表上使用它快?

如果有人能够帮助我更好地理解它们,可能通过举几个例子来说明什么时候使用,那真是太棒了。

你已经给出了一个相当不错的总结,所以在任何情况下,其中一个重要的事情应该帮助你决定使用哪一个。

思考的方式是列表是开放式的数据结构,它们的大小可以在运行时变化,而元组在编译时具有恒定的大小。

例如,如果您想存储用户在iex会话期间给出的所有命令,则需要一个列表 – 该列表的长度将取决于该会话中给出的命令的数量。 将其与一个典型的元组用法相比较 – 从一个方法返回{:ok, result}{:error, reason} – 这里元素的数量是预先知道的,所以你不支付一个不可接受的价格Tuples的性能改进。

至于枚举 – 元组概念上不是集合,每个元素的位置也应该表示它的作用。 考虑一个{:ok, #PID<0.336.0>}元组 – 迭代它会首先给你一个:ok ,然后一个#PID<0.336.0> ,写一个统一的函数是很奇怪的这些东西的方式。

我不是专家,但这是我的理解:

在引擎盖下,一个列表是一个链表。 因此它具有链表的性能特征。 也就是说,得到的长度是O(n),因为我必须走整个列表。 同样,列表也具有链表的优点。 也就是说,通过添加到前面很容易增长它。

我不确定元组是什么,但我知道这不是一个链表。 有人问到2013年在Elixir语言邮件列表中枚举元组,这是响应的一部分:

“元组也不意味着被迭代,不要因为你可以使用elem / 2和size / 1这个事实而被混淆。元组是用来存储多条信息在一起的,这并不意味着它们是有意的用于存储集合“。

– Peter Minten

“另一种解释是元组是穷人的logging,换句话说,一个元组代表一个单一的数据,一个单一的值,尽pipe是聚合的。你不能从元组中拿走一个元素而不改变该特定元组的语义值。

“这与列表和其他集合存储许多值独立的值是相反的,从列表中取出一个值会减less列表的长度,不影响任何事物的语义含义。

– 阿列克谢Sholik

换句话说,就是因为元组和列表之间有一种肤浅的相似之处,我们不应该假设行为是一样的。

除了已经说过的之外,帮助我从列表中区分一个元组的东西,与数据库中的一行类似。 如果以这种方式来考虑元组,就很容易看出元组中的信息是如何相互关联的,而且这也很明显,为什么你不把它用作Enumerable。

由于有人提到他们不确定引擎盖下的元组是什么,所以元组将类似于数组,因为数组和元组都将元素存储在连续的内存中。 所以,当你在一个链表上使用一个数组的时候,同样的规则会跟在Elixir的一个列表上。

如果您熟悉Java:

  • 列表就像一个LinkedList
  • 元组就像一个ArrayList