所以我开始学习Erlang,我对这段代码有点迷惑。
-module(prior).
-compile(export_all).
important() ->
receive
{ Priority, Msg } when Priority > 10 ->
[Msg | important()]
after 0 ->
normal()
end.
normal() ->
receive
{ _, Msg } ->
[Msg | normal()]
after 0 ->
[]
end.我正在使用调用代码。
10> self() ! {15, high}, self() ! {7, low}, self() ! {1, low}, self() ! {17, high}.
{17,high}
11> prior:important().
[high,high,low,low]我知道这段代码将首先遍历所有高优先级的消息,然后是低优先级的消息。我搞不懂返回值是高,高,低,低,因为我看不到它们连接在一起的地方。
发布于 2012-06-11 08:46:07
最终返回值的构造方式...
当第一次返回[Msg | important()]时,确定最终返回值的形式。唯一需要注意的是,我们还不知道最终返回值的所有细节。因此,[Msg | important()]中的important()将继续被评估。下面是如何构造最终返回值[high,high,low,low]的示例。
[high | important( )] <---- Defines the final form
---------------------------------
[high | important( )] <---- Adds more details
------------------------
normal( ) <---- Adds more details
------------------------
[low | normal( )] <---- Adds more details
----------------
[low | normal()] <---- Adds more details
--------
[ ] <---- Adds more details
------------------------------------------
[high | [high | [low | [low | []]]]]
[high,high,low,low] <---- The final return value代码的工作原理...
在函数important/0中,after 0仅仅意味着“我不等待消息的到来”--如果我的邮箱中有任何消息,我将查看它;如果没有消息,我将继续执行(执行normal()),而不是在那里等待。在邮箱中,已经有{15,高},{7,低},{1,低},{17,高}。在Erlang中,邮箱中的消息是按先到先服务的顺序进行而不是排队的。receive子句可能很挑剔。它扫描邮箱中的所有邮件,并“挑选”它想要的邮件。在我们的例子中,根据{Priority, Msg} when Priority > 10,首先选择{15,高}和{17,高}。在此之后,函数normal/0将接管。和{7,low},{1,low}按顺序处理(consed)。最后,我们得到了[high,high,low,low]。
显示处理顺序的修改版本...
我们可以稍微修改一下代码,以使处理(协调)顺序更明确:
-module(prior).
-compile(export_all).
important() ->
receive
{Priority, Msg} when Priority > 10 ->
[{Priority, Msg} | important()] % <---- Edited
after 0 ->
normal()
end.
normal() ->
receive
{Priority, Msg} -> % <---- Edited
[{Priority, Msg} | normal()] % <---- Edited
after 0 ->
[]
end.在shell中运行它:
4> c(prior).
{ok, prior}
5> self() ! {15, high}, self() ! {7, low}, self() ! {1, low}, self() ! {17, high}.
{17,high}
6> prior:important().
[{15,high},{17,high},{7,low},{1,low}]发布于 2012-06-11 04:09:49
它们在这里连接在一起
[Msg | important()]这个important()是一个函数,所以它有一个返回值,当你在REPL中运行它时,他会打印出来自函数的返回值。此值是从import()构建[Head | Tail]列表的效果
important()这里是一个常规函数:)
它有帮助吗?
发布于 2012-06-11 08:44:05
所有Erlang函数总是返回值。函数important/0将接收高优先级消息,然后在表达式[Msg | important()]中递归地调用自身,该表达式构建了一个列表,其中包含最新的Msg和important/0将接收的所有其他消息。从important/0返回的就是这个列表。当没有更多的高优先级消息时,important/0将改为调用normal/0来读取所有剩余消息。与important/0相同,normal/0读取的消息将以列表的形式返回。这将被返回给important/0,然后它将在返回消息的相同列表中返回它。
请注意,一旦调用了normal/0,就不会再对高优先级消息进行特殊处理,因为再也不会调用important/0了。此外,important/0实际上只会处理队列中已经存在的高优先级消息,因为一旦它找不到更多的消息,它就会调用normal/0。
超时值0的特殊之处在于它会立即超时,但保证首先在整个消息队列中搜索匹配的消息。
https://stackoverflow.com/questions/10971923
复制相似问题