3

これは私のコードです:

    lists:foreach(fun(Method, Value)->
                      ServerName = method_to_servername(Method),
                      if
                          Value ==0 andalso whereis(ServerName) =/= undefined ->
                              supervisor:terminate_child(flowrate, whereis(ServerName));
                          Value =/= 0 andalso whereis(ServerName) == undefined ->
                              supervisor:start_child(?MODULE, [Method]);
                          Value =/=0 andalso whereis(ServerName) =/= undefined ->
                              gen_server:call(method_to_servername(Method),
                                              {update_config,
                                               {DesAddress, Method, RateLimitList,
                                                QueueTime,
                                                MinRetry, MaxRetry, Callback}} );
                          true -> ok
                      end
              end, ?ALL_METHODS).

コードをコンパイルすると、この問題が発生illegal guard expressionします。アドバイスをいただけますか。

4

2 に答える 2

3

式のテストはifガード シーケンスと呼ばれます。ガード シーケンスでは限られた数の関数のみが許可されておりwhereis、それらの関数の 1 つではありません。完全なリストについては、Erlang リファレンス マニュアルのガード シーケンスのセクションを参照してください。

結果として、ほとんどの Erlang プログラマーはめったに使用しませんif。を頻繁に使用caseすると、より自然で簡潔なコードが得られます。あなたの例は次のように書くことができます:

lists:foreach(fun(Method, Value)->
                  ServerName = method_to_servername(Method),
                  case {Value, whereis(ServerName)} of
                      {0, ServerPid} when is_pid(ServerPid) ->
                          supervisor:terminate_child(flowrate, ServerPid);
                      {_, undefined} when Value =/= 0 ->
                          supervisor:start_child(?MODULE, [Method]);
                      {_, ServerPid} when is_pid(ServerPid) ->
                          gen_server:call(method_to_servername(Method),
                                          {update_config,
                                           {DesAddress, Method, RateLimitList,
                                            QueueTime,
                                            MinRetry, MaxRetry, Callback}} );
                      _ -> ok
                  end
          end, ?ALL_METHODS).
于 2013-08-31T11:44:45.817 に答える
0

このコードには、いくつかの問題があります。

  1. lists:foreach/2最初の引数としてアリティ 1 を使用する必要があります。これに似た ?ALL_METHODS マクロが定義されていると思います:次に、fun の引数をタプルでラップすること-define(ALL_METHODS, [{method1, 1}, {method2, 2}, ...])で修正できます:fun(Method, Value)fun({Method, Value})
  2. whereis(ServerName) =/= undefined競合状態が発生する可能性があるため、最初にwhereis(ServerName)戻ったときにpid()、何らかの理由でプロセスが停止し、次のステップで停止しますundefined(ただし、コンテキストなしで 100% 確実とは言えません)。
  3. あなたはmethod_to_servername(Method)2回行います。

あなたの質問についてですが、Erlang のガード関数は関数の特定のサブセットのみを許可します。

于 2013-09-02T07:44:34.950 に答える