【问题标题】:Process crashes on second message in ErlangErlang 中第二条消息的进程崩溃
【发布时间】:2013-04-09 00:38:35
【问题描述】:

我在 Erlang 中实现了一个简单的汽车流程:

-module(cars).
-compile(export_all).

-record(state, {count=1}).

make_car() ->
  spawn_link(fun() -> car_proc(#state{}) end).

car_proc(S) ->
    receive
        {idle, X} ->
            io:format("idling for ~p second(s)~n", [X]),
            timer:sleep(X*1000);
        {move, {X,Y}} ->
            io:format("move; x=~p, y=~p~n", [X,Y]);
        {stop, Reason} ->
            X = S#state.count,
            io:format("stopped with count ~p because ~p~n", [X+1, Reason])
    end,
    X = S#state.count,
    car_proc(S#state{count=X+1}).

我可以让它空闲,但是如果我连续两次调用空闲,它就会中断:

59> C = cars:make_car().
<0.207.0>
60> C!{idle,1}.         
idling for 1 second(s)
{idle,1}
61> C!{idle,1}.         
idling for 1 second(s)
{idle,1}
62> 
=ERROR REPORT==== 9-Apr-2013::00:00:00 ===
Error in process <0.207.0> with exit value: {{badmatch,2},[{cars,car_proc,1,[{file,"cars.erl"},{line,20}]}]}

** exception error: no match of right hand side value 2
     in function  cars:car_proc/1 (cars.erl, line 20)

为什么?

【问题讨论】:

    标签: erlang shadowing


    【解决方案1】:

    错误发生在第20行,即

    X = S#state.count
    

    这是因为模式匹配失败。变量'X'已经在这一行定义了,它的值为1,因为它已经在接收块中确定了:

    receive
            {idle, X} ->
    

    在 Erlang 中,变量的值只能定义一次。当您第一次发送消息 {idle, 1} 时,X 变为 1,并且 S#state.count 的默认值为 1。所以在这种情况下,“X”匹配 S#state.count。当您第二次发送 {idle, 1} 时,X 为 1,S#state.count 为 2(即 X 和 S#state.count 不相等)。所以你会在模式匹配中遇到错误。您可以使用另一个变量来避免该问题。更改最后两行

    X = S#state.count,
    car_proc(S#state{count=X+1}).
    

    Count = S#state.count,
    car_proc(S#state{count=Count+1}).
    

    要快乐!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      • 2012-04-27
      • 2023-03-31
      • 1970-01-01
      • 2016-04-30
      • 2012-03-03
      • 2016-04-30
      相关资源
      最近更新 更多