Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1879542
  • 博文数量: 217
  • 博客积分: 4362
  • 博客等级: 上校
  • 技术积分: 4180
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-20 09:31
文章分类

全部博文(217)

文章存档

2017年(1)

2015年(2)

2014年(2)

2013年(6)

2012年(42)

2011年(119)

2010年(28)

2009年(17)

分类: Python/Ruby

2011-08-02 09:54:42

    在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. 1> A={apple, orange, bag, love}.
  2. {apple,orange,bag,love}
  3. 2> {B, C, _, _} = A.
  4. {apple,orange,bag,love}
  5. 3> B.
  6. apple
  7. 4> C.
  8. orange
    对于列表的提取例子如下:
  1. 12> f().
  2. ok
  3. 13> A=[fanying].
  4. [fanying]
  5. 14> B=[yingfei|A].
  6. [yingfei,fanying]
  7. 15> C=[flying|B].
  8. [flying,yingfei,fanying]
  9. 16> [F|M]=C.
  10. [flying,yingfei,fanying]
  11. 17> F.
  12. flying
  13. 18> M.
  14. [yingfei,fanying]
  15. 19>
    每一次“[Head|End]=F.”中,Head提取出来的是一个元素,而End提取出来的是还是一个列表。
    这里我们还有一个需要注意的地方,在我们写erlang程序的时候,通常的返回值如果是元组的话,我们使用一个变量进行匹配是可以的。例如:
  1. ^_^[sunny@sunny-laptop ~/erl_test]2$ cat fan.erl 
  2. -module(fan).

  3. -export([test/0]).

  4. test() ->
  5. case fun_test() of
  6. false ->
  7. io:format("Result is error!~n");
  8. {Result} ->
  9. io:format("Result is ~p~n", [Result])
  10. end.

  11. fun_test() ->
  12. {fanying}.    %%{fanying, yingfei, fei} 这个返回值上面的匹配是有问题的
  13. ^_^[sunny@sunny-laptop ~/erl_test]3$ 
    在fun_test()函数中返回一个元组,这个元组在test()函数中使用一个变量进行匹配是可以的。当我们把fun_test()的返回值的元组的元素个数改为不止一个的时候,就会出现问题,因此一般我们再返回值列表的元素个数不确定的情况下,我们最好使用一个变量(去掉{}的方式来接收)来进行接收,而不是一个带有{Result}的方式进行接收。
    我们将上面的fun_test()函数返回的那个元组如果改为一个列表,结果会怎样呢?我们继续往下看:
  1. ^_^[sunny@sunny-laptop ~/erl_test]3$ cat fan.erl
  2. -module(fan).

  3. -export([test/0]).

  4. test() ->
  5.     case fun_test() of
  6.         false ->
  7.             io:format("Result is error!~n");
  8.         [Result] ->
  9.             io:format("Result is ~p~n", [Result])
  10.     end.

  11. fun_test() ->
  12.     [fanying].    %%[fanying, yingfei, fei] 这个返回值上面的匹配是有问题的
  13. ^_^[sunny@sunny-laptop ~/erl_test]4$
    在fun_test()函数中返回了一个只有一个元素的列表,这个时候我们使用[Result]的形式进行匹配是正确的,但是如果我们将这个返回值改为[fanying, yingfei, fei]式的时候,就会出现问题。因此,如果返回值是一个列表,这个时候我们进行匹配的时候,最好使用变量来进行匹配,使用列表的“提取元素”方式进行元素的提取。
    对于这个问题我们在erlang编程的时候要切记,当初我就是由于疏忽了这一点,花费了很长的时间最后才找到了这个错误。

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

阅读(4059) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~