在erlang程序设计中,元组与列表本人很容易混淆,不知道什么时候应该使用元组,什么时候应该使用列表,为此,我查阅了一些网上的资料,并添加了一些
自己的理解,如果有理解不到位的地方,欢迎大家指正。
元组:
将一定数量项组成在一起,就形成了一个单一的实体,并且若干个项之间使用逗号隔开,形成的整个实体使用{}括起来,这样就形成了一个元组。这个元组的概念有点像c语言中的结构体,因为在erlang程序中并没有结构体这个概念,因此为了描述一个实体多方面的属性值的时候就引用了这个概念,我们可以把这个元组的概念和c语言中的结构体概念对比着理解。另外,一旦元组创建之后,元组项的个数就不能再变化了。其实元组就是原子。
例如,我们要描述一台电脑的时候可以这么来描述:
{sunny_computer, {name, asus}, {memory, 2048}, {disk, 300}}
细心的人可能发现,在这个元组当中我又一次嵌套了元组,是的,元组是可以嵌套的。
总结一下:元组也是一个原子。
列表:
将不定数量的项组在一起,再加上[]括号,就形成了列表。列表的每一项可以是元组,也可以仍是列表,即列表是可以允许嵌套使用的。
和元组的主要区别是列表是存储可变数目的东西,创建一个列表之后,我们仍然可以往其中增加项,当然可以删除项,因此列表使用的话比较灵活一些。
例如,我们要描述张三买了一台电脑,李四买了一件新衣服:
[{zhangsan, computer}, {lisi, clothes}]
接着李四卖掉新衣服,买了一个外星人,王五买了拖拉机,准备当农民,这样的话,列表就变成了这样的:
[{zhangsan, computer}, {lisi, ET}, {wangwu, tractor}]
由此我们可以看出,列表中的项的个数是可以变化的,数目不定。
元组与列表对比:
(1)从创建的角度来说。
在声明元组的时候,就自动创建了一个元组。
而对于列表来说,创建一个列表有两种方式,一种是直接定义,例如:F=[abc];另外一种是在已经创建的基础上再次添加一个项,那新构成的这个仍然是列表。
(2)从提取的角度来说。
从元组中提取字段值的时候,我们一般使用的是“=”来提取,而对于列表来说,使用的仍然还是模式匹配,只不过对于列表来说的话,我们每一次只能提取这个列表的头部,也就说一次只能提取一个项。
例如,对于元组提取元素的使用如下:
- 1> A={apple, orange, bag, love}.
-
{apple,orange,bag,love}
-
2> {B, C, _, _} = A.
-
{apple,orange,bag,love}
-
3> B.
-
apple
-
4> C.
-
orange
对于列表的提取例子如下:- 12> f().
-
ok
-
13> A=[fanying].
-
[fanying]
-
14> B=[yingfei|A].
-
[yingfei,fanying]
-
15> C=[flying|B].
-
[flying,yingfei,fanying]
-
16> [F|M]=C.
-
[flying,yingfei,fanying]
-
17> F.
-
flying
-
18> M.
-
[yingfei,fanying]
-
19>
每一次“[Head|End]=F.”中,Head提取出来的是一个元素,而End提取出来的是还是一个列表。 这里我们还有一个需要注意的地方,在我们写erlang程序的时候,通常的返回值如果是元组的话,我们使用一个变量进行匹配是可以的。例如:
- ^_^[sunny@sunny-laptop ~/erl_test]2$ cat fan.erl
- -module(fan).
- -export([test/0]).
- test() ->
- case fun_test() of
- false ->
- io:format("Result is error!~n");
- {Result} ->
- io:format("Result is ~p~n", [Result])
- end.
- fun_test() ->
- {fanying}. %%{fanying, yingfei, fei} 这个返回值上面的匹配是有问题的
- ^_^[sunny@sunny-laptop ~/erl_test]3$
在fun_test()函数中返回一个元组,这个元组在test()函数中使用一个变量进行匹配是可以的。当我们把fun_test()的返回值的元组的元素个数改为不止一个的时候,就会出现问题,因此一般我们再返回值列表的元素个数不确定的情况下,我们最好使用一个变量(去掉{}的方式来接收)来进行接收,而不是一个带有{Result}的方式进行接收。
我们将上面的fun_test()函数返回的那个元组如果改为一个列表,结果会怎样呢?我们继续往下看:
- ^_^[sunny@sunny-laptop ~/erl_test]3$ cat fan.erl
-
-module(fan).
-
-
-export([test/0]).
-
-
test() ->
-
case fun_test() of
-
false ->
-
io:format("Result is error!~n");
-
[Result] ->
-
io:format("Result is ~p~n", [Result])
-
end.
-
-
fun_test() ->
-
[fanying]. %%[fanying, yingfei, fei] 这个返回值上面的匹配是有问题的
-
^_^[sunny@sunny-laptop ~/erl_test]4$
在fun_test()函数中返回了一个只有一个元素的列表,这个时候我们使用[Result]的形式进行匹配是正确的,但是如果我们将这个返回值改为[fanying, yingfei, fei]式的时候,就会出现问题。因此,如果返回值是一个列表,这个时候我们进行匹配的时候,最好使用变量来进行匹配,使用列表的“提取元素”方式进行元素的提取。
对于这个问题我们在erlang编程的时候要切记,当初我就是由于疏忽了这一点,花费了很长的时间最后才找到了这个错误。
小结:
个人理解,仅供参考:元组相当于定长的数组,而列表相当于不定长的链表。
阅读(4153) | 评论(0) | 转发(0) |