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 { _,

所以我开始学习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]
我知道这段代码将首先遍历所有高优先级消息,然后遍历低优先级消息。我对返回值是如何[高、高、低、低]感到困惑,因为我看不出它们在哪里连接在一起。

它们在这里是集中的

[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}]