繁体   English   中英

列表与元组 - 使用什么以及何时使用?

[英]Lists vs. Tuples - What to use and when?

我试图掌握Elixir ListsTuples之间的区别。 从 Elixir Guides 的Basic Types部分,我了解到:

  • 列表存储为链接项目
  • 更新列表很快(仅在前置时)
  • 获取列表项很慢
  • 获取列表信息(大小/长度)很慢
  • 元组元素存储在一起
  • 获取元组信息很快
  • 获取元组元素很快
  • 修改元组很昂贵

好的,这一切都很好,但我仍然不确定何时使用什么 我看到大多数方法都返回一个元组,但在其他任何地方都使用列表,并且许多方法接受列表作为输入,而不是元组。 根据上述几点,元组不应该用于传递数据,因为从用户给定值的元组中读取会很快吗?

我还注意到元组不可枚举,这是怎么回事? 在它们上使用Enum会不会比在 Lists 上使用它更快?

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

您已经对差异进行了很好的总结,因此在其中一项很重要的任何情况下,它应该帮助您决定使用哪一项。

考虑的方式是,列表是开放式数据结构,它们的大小在运行时可能会有所不同,而元组在编译时设置的大小不变。

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

至于枚举 - 元组在概念上不是集合,每个元素的位置也应该表示它的角色。 考虑一个{:ok, #PID<0.336.0>}元组 - 迭代它首先会给你一个:ok然后一个#PID<0.336.0> ,写一个函数会很奇怪在那些事情上。

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

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

我不确定引擎盖下的元组是什么,但我知道它不是链表。 有人在 2013 年询问了 Elixir 语言邮件列表上的枚举元组,这是回复的一部分:

“元组也不应该被迭代,不要被你可以使用 elem/2 和 size/1 的事实弄糊涂了。元组用于将多条信息存储在一起,这并不意味着它们是有意的用于存储集合。”

——彼得·明腾

“另一种解释是元组是穷人的记录。换句话说,元组表示单个数据,单个值,尽管是聚合。你不能在不改变特定元组语义的情况下从元组中删除元素价值。

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

——阿列克谢·肖利克

换句话说,仅仅因为元组和列表之间存在表面相似性,我们不应该假设行为是相同的。

除了已经说过的,帮助我区分元组和列表的是类似于数据库中的一行。 如果您以这种方式考虑元组,则很容易看出元组中的信息是如何相互关联的,并且为什么不将其用作 Enumerable 的原因也变得显而易见。

如果您熟悉 Java:

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

由于有人提到他们不确定元组在幕后类似于什么,元组将类似于数组,因为数组和元组都将元素存储在连续内存中。 因此,当您在链表上使用数组时,将遵循相同的规则,就像在 Elixir 中在列表上使用元组时一样。

元组旨在保存固定数量的元素,这就是它们预先分配内存的原因。 基本上元组并不意味着改变(虽然它是可能的但很昂贵)。 它们提供了一条相关信息。

例如:地理坐标 {43.258389, -2.924405}

相反,列表更适合动态集合(修改它们的成本更低)。

我发现这篇文章非常有用: https : //blog.appsignal.com/2018/08/21/elixir-alchemy-list-vs-tuples.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM