Erlang中列表和元组之间的主要区别是什么?模式匹配如何区分每个.
@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]).
但实际上,你通常以这样的方式设计你的函数,你知道,如果它需要元组或列表并使用模式匹配来获取元素.如果您知道它有多少元素,您可以像这样模式匹配列表:
[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.