Erlang中List和Tuple之间的区别

Rah*_*hul 2 erlang functional-programming

Erlang中列表和元组之间的主要区别是什么?模式匹配如何区分每个.

tko*_*wal 9

@Arunmu提供的链接回答了问题的第一部分.您可以使用警卫来区分这些数据结构:

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]).
Run Code Online (Sandbox Code Playgroud)

但实际上,你通常以这样的方式设计你的函数,你知道,如果它需要元组或列表并使用模式匹配来获取元素.如果您知道它有多少元素,您可以像这样模式匹配列表:

[A, B, C] = [1, 2, 3] # A becomes 1, B becomes 2, C becomes 3
Run Code Online (Sandbox Code Playgroud)

但通常,您可以利用列表递归性质.每个列表都是:

  • 空列表
  • 或者它由头部(第一个元素)和尾部组成.

这是模式匹配,你经常会使用:

[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
Run Code Online (Sandbox Code Playgroud)

因此处理列表的函数通常是递归的:

do_stuff([]) ->
     finished; # there are no more elements
do_stuff([H | T]) ->
     do_something_with(H),
     do_stuff(T).
Run Code Online (Sandbox Code Playgroud)

所以你不必知道列表的长度是多少来处理所有元素.当你使用元组时,你知道它们有多大.典型的模式匹配是:

{A, B} = {lol, rotfl} # A becomes lol, B becomes rotfl
{A, _} = {troll, trololo} # A becomes troll
Run Code Online (Sandbox Code Playgroud)

元组经常用于标记事物.当您收到来自其他进程的消息时,请使用receive

receive
    Request -> do_something_with(Request)
end.
Run Code Online (Sandbox Code Playgroud)

但我们不知道,如果请求有效或者某些其他进程错误地发送了某些内容.我们可以使用atom标记Request request并确保调用进程始终指定自己的pid:

receive
    {request, Pid, Request} ->
        Response = do_something_with(Request),
        Pid ! Response;
    _ -> ignore_message
end.
Run Code Online (Sandbox Code Playgroud)


aro*_*tav 5

它们是不同的数据类型,具有不同的实现和操作成本:

元组通常用于表示可能不同类型固定数量值的集合,您希望能够在恒定时间内访问任何值。它们还用于在不使用异常的情况下区分正常返回(例如)和错误返回(例如)。{ok, Value}error

列表通常用于表示相同类型任意数量值的集合,您希望能够以迭代方式(例如使用 a或操作)处理元素。mapfold

匹配元组的模式(例如{A,B,C}),通常匹配特定大小的元组和/或某些元素的特定值。

匹配列表的模式(例如[H|T]),通常与 first 和 rest 元素匹配。