Erlang中列表和元组之间的主要区别是什么?模式匹配如何区分每个。
答案 0 :(得分:9)
@Arunmu提供的link回答了问题的第一部分。您可以使用警卫区分这些数据结构:
do_something(List) when is_list(List) ->
io:format("I got the list ~p", [List]);
do_something(Tuple) when is_tuple(Tuple) ->
io:format("I got tuple ~p", [Tuple]).
但实际上,你通常以这样一种方式设计你的函数,你知道,如果它采用元组或列表并使用模式匹配来获取元素。如果您知道它有多少元素,您可以像这样模式匹配列表:
[A, B, C] = [1, 2, 3] # A becomes 1, B becomes 2, C becomes 3
但通常,您可以利用列表递归性质。每个列表都是:
这是模式匹配,你经常会使用:
[H | T] = [1, 2, 3] # H becomes 1, T becomes [2, 3]
[H2 | T2] = [1] # H becomes 1, T becomes []
[H3 | T3] = [] # gives error badmatch
因此处理列表的函数通常是递归的:
do_stuff([]) ->
finished; # there are no more elements
do_stuff([H | T]) ->
do_something_with(H),
do_stuff(T).
所以你不必知道列表的长度是多少来处理所有元素。当你使用元组时,你知道它们有多大。典型的模式匹配是:
{A, B} = {lol, rotfl} # A becomes lol, B becomes rotfl
{A, _} = {troll, trololo} # A becomes troll
元组经常用于标记事物。当您收到来自其他流程的消息时,请使用receive
receive
Request -> do_something_with(Request)
end.
但我们不知道,如果请求有效或者某些其他进程错误地发送了某些内容。我们可以使用atom request
标记Request,并确保调用进程始终指定自己的pid:
receive
{request, Pid, Request} ->
Response = do_something_with(Request),
Pid ! Response;
_ -> ignore_message
end.
答案 1 :(得分:4)
它们是不同的数据类型,具有不同的实现和操作成本:
元组,通常用于表示可能不同类型固定数量值的集合 ,您希望能够在恒定时间内访问任何值。它们还用于区分正常返回(例如{ok, Value}
)与错误返回(例如error
)而不使用异常。
列表,通常用于表示相同类型的任意数量值的集合 ,您希望能够以迭代方式处理元素(例如,使用map
或fold
操作)。
与元组匹配的模式(例如{A,B,C}
)通常与特定大小的元组和/或某些元素的特定值匹配。
与列表匹配的模式(例如[H|T]
)通常与第一个和其余元素匹配。
答案 2 :(得分:2)
我会尝试回答何时使用元组或列表。它们都是erlang术语的集合,因为它们不像任何其他erlang变量那样可变,所以差异不是固定大小。
元组:当您在编写程序时知道它将包含多少条款时,您将使用元组,当所有条款具有特殊含义并且您将能够使用它们访问它们时位置。一个很好的例子可以是点P = {X,Y,Z}的坐标。
当您认为应用程序的未来发展可能会在集合中引入新术语时,您可能会选择一条记录:具有一些语法功能的命名元组,以按名称访问每个元素,示例是代表员工的记录(姓名,地址,出生地,代码,技能列表)也许您稍后会添加一个电话号码,一封电子邮件......
经常使用的是返回多个值或标记值({ok,Value},{error,Reason})。
列表:列表可以递归定义:它可以是空列表[],也可以是2个元素的构造,即Head和Tail,其中head可以是任何erlang术语,并且尾部是一个列表(我说的只是正确的列表)。当您无法知道何时编写程序时,您将使用此列表。服务器可以在列表中存储连接的客户端的名称。你通常会递归地查看一个列表,所以元素通常是一致的(名称列表,pid列表......)或者使用类似于proplist的“typed”。
这两个元素是更复杂数据结构的基础砖(如树
)答案 3 :(得分:1)
基本上,两者都用于完全不同的目的。
元组
1.syntax:{a ,b, c .. z}.
2.Purpose:当您希望某些数据按特定模式分组时,您将使用元组。
例如,我需要昨天的日落和日出时间,我更有可能在这里使用元组而不是列表,记录,ordict等,因为它完全适合该法案。{sunrise,7.00},{sunset,18.30}
3.Pattern Matching:Tuple支持模式匹配。这就是它的完成方式
tuplePatternMatching({A,B},{C,D}) ->
io:format("~p ~p",A @ B),
io:format("~p ~p",C @ D) . #sunrise @ 7 #sunset at 18.30
列表
1.pntax:[a,b,c .. z]。2.目的:一般情况下,我们在需要一些数据时使用它,共享共同的性质被组合在一起。
例如,我需要过去7天的日落时间,我更有可能在这里使用List而不是元组,记录,ordict等。Sunset = [18,18.01,18.02,18.03,18.04,18.05,18.06]
3.Pattern Matching,Recursion,Operations:List也支持模式匹配,但我们也将它用于不同的目的。 它由head和tail组成。这构成了像Erlang这样的语言的Recursion的基础,它不支持像while / for这样的循环结构。
上面列出的是18 尾巴是剩下的部分:18.01,18.02,18.03,18.04,18.05,18.06
Sunset = [ 18 | 18.01,18.02,18.03,18.04,18.05,18.06] # i.e [ A | B,C] = [A,B,C]
打印每个元素的示例程序:
SunsetFunction([]) -> ok;
SunsetFunction([H|T) ->
io:format("~p ~p",H),
SunsetFunction(T).
列表可以包含任何数据类型:
[Atom,{Tuple,Var},List] eg. ['hello@rahul',{rahul,Coder},[20,30,40]]