erlang中的元组与列表的区别与联系

传送门:http://blog.chinaunix.net/space.php?uid=22566367&do=blog&id=1993490


在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编程的时候要切记,当初我就是由于疏忽了这一点,花费了很长的时间最后才找到了这个错误。

小结:
个人理解,仅供参考:元组相当于定长的数组,而列表相当于不定长的链表。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值