元组在内存里是连续存储的,使用它有一个限制:必须提前知道它内部有多少元素。可是,我们有时无法预计元素的数量,而且在表达式中写出大量的元素也不现实。为解决这些问题,Elixir为我们提供了列表数据类型。Elixir的列表是链表,其中每一项都包含一个值和对下一个元素的隐式引用。图3-2显示了列表[:a,:b,:c,:d,:e]在内存中的存储情况。
图3-2 列表的存储示意图
以空元素结尾的列表是合规列表(proper list),它可以避免无限循环,只要检查到列表最后一项为空,就能停止递归迭代。在极少数情况下,您可能会遇到违规列表(improper list),它的最后一项不是空的。
像元组一样,我们可以借助模式匹配表达式从列表中提取值并将它们放入变量,或者检查列表项是否符合某些模式。列表用[]表示。让我们先试试以下几个表达式:
模式[a,a,a]表示列表的三个元素必须有相同的值,因为三项都是变量a,而变量在表达式中只能有唯一的值。变量a不能同时是1和2。所以列表[1,2,1]与[a,a,a]无法匹配,却与[a,b,a]匹配成功。再创建一个更复杂的检查:
模式[a,a,"pineapples"]表示前两项必须是相同的值,第三项必须是pineapples。
如果想忽略列表的某些部分,可以使用通配符_。试试这两个表达式:
我们用通配符告诉Elixir不希望检查某些元素。通配符不是列表特有的,它可以用于所有模式匹配表达式和数据类型。
Elixir为列表提供了一个特殊的运算符|。它可以将列表中的一些元素与其余元素分开,以便处理未知大小的列表。让我们试试用|分隔列表元素。
|运算符左侧匹配列表的第一项;右侧剩余的列表元素匹配。第一项绑定到变量head,其余项绑定到变量tail。(通常用head表示列表的首项,用tail表示剩余项。)我们将列表的第一个元素与其余元素分开了。这种方式能从列表中提取值,而不用关心它的大小。
我们看看将|运算符用于仅有一个元素的列表时会发生什么。你能猜出head和tail的值吗?
head的值为:a,tail的值是一个空列表。Elixir将唯一的元素提取到变量head后,剩下的就是一个空列表。再看看在空列表中使用|运算符会发生什么。(www.xing528.com)
由于我们无法分离空列表的元素,因此会引发MatchError。我们还可以在|运算符的左侧提取多个元素。
我们将前两个元素绑定到变量a和b。我们可以绑定更多变量或使用相同的变量名来检查一些模式。使用|运算符可以在不知道列表大小的情况下访问部分列表。下一章会讲解|运算符的其他用途,比如对每个列表项进行计算。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。