ERLANG - 模式匹配

时间:2010-08-12 06:47:22

标签: erlang design-patterns matching

我有一个变量:

Data = [[<<>>, 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]] 

我正在尝试为两个特定情况进行模式匹配..

任何类似于外部结构的东西 - 只需[] 里面有什么东西我试过[ _ ]但是没有去?

第二,对于内部的特定模式,就像我看到&lt;&lt;“10”&gt;&gt;或&lt;&lt;“112”&gt;&gt;或&lt;&lt;“52”&gt;&gt;那么我将把实际数据的右侧带入原子。 基本上&lt;&lt;“10”&gt;&gt;或&lt;&lt;“112”&gt;&gt;或&lt;&lt;“52”&gt;&gt;是字段,右边是数据。

我尝试过像[<<"10">>, _ ]这样的陈述仍然没有去

以下是代码的其余部分:

dataReceived(Message) ->
    receive
        {start} -> 
            ok;

        [ _ ] ->   %%No go
            io:format("Reply 1 = ~p~n", [Message]);

                [<<"10">>, _ ] ->   %%No go
            io:format("Reply 1 = ~p~n", [Message])


    end.

作为注释,消息不作为元组发送,它与Data =

完全相同

有人能引导我朝正确的方向前进吗?

谢谢,晚安! -B

更新

好的,现在我觉得我变暖了,我必须模仿匹配任何内容。

所以如果我说了

Message = = [[<<>>], 
 [<<"10">>,<<"171">>],
 [<<"112">>,<<"Gen20267">>],
 [<<"52">>,<<"20100812-06:32:30.687">>]]

我希望模式匹配字段&lt;&lt;“112”&gt;&gt;

如112总是会说112,但Gen2067可以随时改变......它的数据,它将存储在一个变量中。

loop() ->
receive
    [_,[<<"112">>, Data], _] when is_list(X) -> %% Match a list inside another.
        ?DEBUG("Got a list ~p~n", [X]),
        loop();
    _Other ->
        ?DEBUG("I don't understand ~p~n", [_Other]),
        loop()
end.

我觉得我很接近,但不是100%

-B

1 个答案:

答案 0 :(得分:2)

更新 OP正在尝试将参数传递给函数而不发送消息。

如名称所示,receive块用于接收和处理发送给进程的消息。当您使用参数调用dataReceived时,它会继续等待消息。由于没有发送消息,它将继续无休止地等待。给定当前代码,如果您希望它执行某些操作,那么您将必须生成该函数,获取进程ID,然后向进程ID发送消息。

您可能需要一个函数,其中参数是模式匹配的,而不是消息

这样的事情:

dataReceived([Message]) when is_list(Message) ->
    io:format("Got a list as arg ~p~n", [Message]);
dataReceived(_Other) ->
    io:format("Unknown arg ~p~n", [_Other]).

另一方面,您的第三个模式[X] when is_list(X)永远不会匹配,因为第二个模式是第三个模式的超集。匹配[X] when is_list(X)的任何内容都将始终与[X]匹配,因此您的第三个匹配子句将永远不会被触发。

原始答案

我不确定我理解你的问题。您是在尝试向该函数发送消息还是将其传递给参数?

如果您 发送消息 ,这是关于如何匹配列表列表的部分答案。

-module(mtest).
-export([run/0]).

-ifdef(debug).
-define(DEBUG(Format, Args), io:format(Format, Args)).
-else.
-define(DEBUG(Format, Args), void).
-endif.

loop() ->
receive
    [X] when is_list(X) -> %% Match a list inside another.
        ?DEBUG("Got a list ~p~n", [X]),
        loop();
    _Other ->
        ?DEBUG("I don't understand ~p~n", [_Other]),
        loop()
end.

查看receive块中的第一个子句。 [X] when is_list(X)会将内部列表绑定到名称X。我用你提供的Data的值测试了它并且它有效。

%% From the shell.
1> c(mtest, {d, debug}).
{ok,mtest}
2> Pid = mtest:run().
<0.40.0>
3> Data = [[<<>>, [<<"10">>,<<"171">>], [<<"112">>,<<"Gen20267">>], [<<"52">>,<<"20100812-06:32:30.687">>]]].
[[<<>>,
  [<<"10">>,<<"171">>],
  [<<"112">>,<<"Gen20267">>],
  [<<"52">>,<<"20100812-06:32:30.687">>]]]
4> Pid ! Data.
[[<<>>,
  [<<"10">>,<<"171">>],
  [<<"112">>,<<"Gen20267">>],
  [<<"52">>,<<"20100812-06:32:30.687">>]]]
Got a list [<<>>,
            [<<"10">>,<<"171">>],
            [<<"112">>,<<"Gen20267">>],
            [<<"52">>,<<"20100812-06:32:30.687">>]]
5>