首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Erlang中的选择性接收

Erlang中的选择性接收
EN

Stack Overflow用户
提问于 2012-06-11 04:02:24
回答 3查看 1.4K关注 0票数 11

所以我开始学习Erlang,我对这段代码有点迷惑。

代码语言:javascript
复制
 -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.

我正在使用调用代码。

代码语言:javascript
复制
    10> self() ! {15, high}, self() ! {7, low}, self() ! {1, low}, self() ! {17, high}.
    {17,high}
    11> prior:important(). 
        [high,high,low,low]

我知道这段代码将首先遍历所有高优先级的消息,然后是低优先级的消息。我搞不懂返回值是高,高,低,低,因为我看不到它们连接在一起的地方。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-11 08:46:07

最终返回值的构造方式...

当第一次返回[Msg | important()]时,确定最终返回值的形式。唯一需要注意的是,我们还不知道最终返回值的所有细节。因此,[Msg | important()]中的important()将继续被评估。下面是如何构造最终返回值[high,high,low,low]的示例。

代码语言:javascript
复制
[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]

显示处理顺序的修改版本...

我们可以稍微修改一下代码,以使处理(协调)顺序更明确:

代码语言:javascript
复制
-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中运行它:

代码语言:javascript
复制
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}]
票数 17
EN

Stack Overflow用户

发布于 2012-06-11 04:09:49

它们在这里连接在一起

代码语言:javascript
复制
[Msg | important()]

这个important()是一个函数,所以它有一个返回值,当你在REPL中运行它时,他会打印出来自函数的返回值。此值是从import()构建[Head | Tail]列表的效果

important()这里是一个常规函数:)

它有帮助吗?

票数 4
EN

Stack Overflow用户

发布于 2012-06-11 08:44:05

所有Erlang函数总是返回值。函数important/0将接收高优先级消息,然后在表达式[Msg | important()]中递归地调用自身,该表达式构建了一个列表,其中包含最新的Msgimportant/0将接收的所有其他消息。从important/0返回的就是这个列表。当没有更多的高优先级消息时,important/0将改为调用normal/0来读取所有剩余消息。与important/0相同,normal/0读取的消息将以列表的形式返回。这将被返回给important/0,然后它将在返回消息的相同列表中返回它。

请注意,一旦调用了normal/0,就不会再对高优先级消息进行特殊处理,因为再也不会调用important/0了。此外,important/0实际上只会处理队列中已经存在的高优先级消息,因为一旦它找不到更多的消息,它就会调用normal/0

超时值0的特殊之处在于它会立即超时,但保证首先在整个消息队列中搜索匹配的消息。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10971923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档