Erlang中的选择性接收
所以我开始学习Erlang,我对这段代码有点困惑Erlang中的选择性接收,erlang,erl,Erlang,Erl,所以我开始学习Erlang,我对这段代码有点困惑 -module(prior). -compile(export_all). important() -> receive { Priority, Msg } when Priority > 10 -> [Msg | important()] after 0 -> normal() end. normal() -> receive { _,
-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]
我知道这段代码将首先遍历所有高优先级消息,然后遍历低优先级消息。我对返回值是如何[高、高、低、低]感到困惑,因为我看不出它们在哪里连接在一起。它们在这里是集中的
[Msg | important()]
这个important()
是一个函数,因此它有一个返回值,当您在REPL中运行它时,他将打印函数的返回值。此值是从import()
important()
这里有一个常规函数:)
它有用吗?所有Erlang函数都会返回一个值。函数
important/0
将接收一条高优先级消息,然后在表达式[Msg | important()]
中递归调用自己,该表达式构建一个列表,其中包含最新的Msg
以及important/0
将接收的所有其他消息。此列表是从重要/0
返回的。当不再有高优先级消息时,important/0
将调用normal/0
读取所有剩余的消息。normal/0
读取的消息将以与important/0
相同的方式作为列表返回。这将返回到important/0
,然后将其返回到与返回消息相同的列表中
请注意,一旦调用了normal/0
,将不会对高优先级消息进行特殊处理,因为不再调用important/0
。另外,important/0
实际上只会处理队列中已经存在的高优先级消息,因为一旦它找不到更多消息,就会调用normal/0
超时值
0
的特殊之处在于它立即超时,但保证首先搜索整个消息队列以查找匹配的消息。如何构造最终返回值…
当第一次返回[Msg | important()]
时,确定最终返回值的形式。唯一的问题是,我们还不知道最终返回值的所有细节。因此,将继续对[Msg | important()]
中的important()
进行评估。下面是如何构造最终返回值[高、高、低、低]
的示例
[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
在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}]
谢谢你的快速回复。因此,即使是从after中的normal()调用接收到的低优先级消息也会连接到[Msg | important()]子句中的高优先级列表?所有内容。另外,如果您想要加载消息,它可能会淹没您的ram,所以您应该将其转换为尾部递归函数。我不知道您想构建什么,因为它通常应该是一个gen_服务器,内部数据结构应具有优先权。您正试图在一个进程消息内执行此操作,但这是有限的,所以一般来说这不是一个好主意。连接是指有两个列表,
L1
和L2
并将它们连接起来:L1++L2
。考虑是当你有一个元素E
和一个列表L
,然后形成扩展列表[E|L]
。我写了OP询问的代码(我相信这是我在了解你一些Erlang方面的优先考虑),我同意这个答案。
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}]