If statement 关于“的用法”;如果;用Erlang语言

If statement 关于“的用法”;如果;用Erlang语言,if-statement,erlang,If Statement,Erlang,这是我的代码: lists:foreach(fun(Method, Value)-> ServerName = method_to_servername(Method), if Value ==0 andalso whereis(ServerName) =/= undefined ->

这是我的代码:

    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).

当我编译代码时,我遇到了这个问题:
非法的保护表达式
,你能给我一些建议吗。

如果
表达式中的测试被称为保护序列。在保护序列中只允许有限数量的函数,并且
whereis
不是其中之一。有关完整列表,请参阅

因此,大多数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).

使用此代码,您会遇到几个问题:

  • 列表:foreach/2
    需要乐趣,将arity 1作为第一个参数,您可以 有两个。我想你有?所有宏定义的方法都相似 对此:
    -define(所有_方法,[{method1,1},{method2,2},…])
    然后您可以将fun的参数包装到元组中进行修复:
    fun(Method,Value)
    将是
    fun({Method,Value})
  • 使用
    whereis(ServerName)=/=undefined
    时,您可能会遇到竞争条件,当
    whereis(ServerName)
    首先返回
    pid()
    时,由于某种原因,进程将终止,下一步将是
    undefined
    (但如果没有上下文,很难说100%确定)
  • 您对服务器名(方法)执行了两次
    method\u
  • 关于你的问题,Erlang中的守卫函数只允许某些函数。

    我建议在守卫中使用“when is_pid(ServerPid)”