【问题标题】:How exactly Erlang receive expression works?Erlang 接收表达式究竟是如何工作的?
【发布时间】:2018-03-17 01:21:40
【问题描述】:
  • 为什么接收表达式有时称为选择性接收?
  • 什么是“保存队列”?
  • after 部分如何工作?

【问题讨论】:

标签: erlang elixir


【解决方案1】:

该过程涉及一个特殊的“保存队列”,当您第一次遇到接收表达式时,您可能会忽略它的存在。

可选地,表达式中可能有一个后段,会使过程稍微复杂化。

接收表达式最好用流程图来解释:

receive
  pattern1 -> expressions1;
  pattern2 -> expressions2;
  pattern3 -> expressions3
after
  Time -> expressionsTimeout
end

【讨论】:

    【解决方案2】:

    为什么接收表达式有时被称为选择性接收?

    -module(my).
    %-export([test/0, myand/2]).
    -compile(export_all).
    -include_lib("eunit/include/eunit.hrl").
    
    start() ->
        spawn(my, go, []).
    
    go() ->
        receive
            {xyz, X} ->
                io:format("I received X=~w~n", [X])
        end.
    

    在 erlang shell 中:

    1> c(my).
    my.erl:3: Warning: export_all flag enabled - all functions will be exported
    {ok,my}
    
    2> Pid = my:start().                
    <0.79.0>
    
    3> Pid ! {hello, world}.
    {hello,world}
    
    4> Pid ! {xyz, 10}.     
    I received X=10
    {xyz,10}
    

    注意发送的第一条消息没有输出,但发送的第二条消息有输出。接收是选择性的:它没有接收到所有消息,它只接收到与指定模式匹配的消息。

    什么是“保存队列”?

    -module(my).
    %-export([test/0, myand/2]).
    -compile(export_all).
    -include_lib("eunit/include/eunit.hrl").
    
    start() ->
        spawn(my, go, []).
    
    go() ->
        receive
            {xyz, X} ->
                io:format("I received X=~w~n", [X])
        end,
        io:format("What happened to the message that didn't match?"),
        receive 
            Any ->
                io:format("It was saved rather than discarded.~n"),
                io:format("Here it is: ~w~n", [Any])
        end.
    

    在 erlang shell 中:

    1> c(my).               
    my.erl:3: Warning: export_all flag enabled - all functions will be exported 
    {ok,my}
    
    2> Pid = my:start().    
    <0.79.0>
    
    3> Pid ! {hello, world}.
    {hello,world}
    
    4> Pid ! {xyz, 10}.     
    I received X=10
    What happened to the message that didn't match?{xyz,10}
    It was saved rather than discarded.
    Here it is: {hello,world}
    

    after 部分如何工作?

    -module(my).
    %-export([test/0, myand/2]).
    -compile(export_all).
    -include_lib("eunit/include/eunit.hrl").
    
    start() ->
        spawn(my, go, []).
    
    go() ->
        receive
            {xyz, X} ->
                io:format("I received X=~w~n", [X])
        after 10000 ->
            io:format("I'm not going to wait all day for a match.  Bye.")
        end.
    

    在 erlang shell 中:

    1> c(my).           
    my.erl:3: Warning: export_all flag enabled - all functions will be exported 
    {ok,my}
    
    2> Pid = my:start().
    <0.79.0>
    
    3> Pid ! {hello, world}.
    {hello,world}
    I'm not going to wait all day.  Bye.4> 
    

    另一个例子:

    -module(my).
    %-export([test/0, myand/2]).
    -compile(export_all).
    -include_lib("eunit/include/eunit.hrl").
    
    sleep(X) ->
        receive
        after X * 1000 ->
            io:format("I just slept for ~w seconds.~n", [X])
        end.
    

    在 erlang shell 中:

    1> c(my).
    my.erl:3: Warning: export_all flag enabled - all functions will be exported 
    {ok,my}
    
    2> my:sleep(5).                   
    I just slept for 5 seconds.
    ok
    

    【讨论】:

      猜你喜欢
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2016-08-07
      • 2015-02-19
      • 2014-12-16
      • 1970-01-01
      • 2011-06-26
      • 2021-08-15
      相关资源
      最近更新 更多