【问题标题】:Warning: use of operator '<' has no effect?警告:使用运算符'<'没有效果?
【发布时间】:2017-09-05 18:25:28
【问题描述】:

我是 erlang 的新手,正在尝试实现一个简单的功能,如下所示:

% * ChatServers is a dictionary of usernames with tuples of the form:
%   {server, Pid, Reference,LoggedInUsers}
get_chat_server([], _) ->        
    undefined;

get_chat_server([Key|_], ChatServers) ->
    {server, Pid, Reference,LoggedInUsers} = dict:fetch(Key,ChatServers),
    LoggedInUsers < 100,
    {server, Pid, Reference,LoggedInUsers};

get_chat_server([_|T], ChatServers) ->        
    get_chat_server(T, ChatServers).

基本上我要做的是找到我的字典中 LoggedInUsers 数小于 100 的第一个元组。

但是,一旦我编译了我的代码,就会收到以下 2 个警告:

main_server_distributed.erl:63:警告:使用运算符“

我对 prolog 有一些经验,据我回忆,这是对模式匹配和递归的有效使用。你能指出我在这里做错了什么吗?提前致谢。

【问题讨论】:

    标签: erlang erlang-otp


    【解决方案1】:

    main_server_distributed.erl:66:警告:此子句无法匹配 因为第 61 行的前一个子句总是匹配

    你基本上写过:

    get_chat_server(NonEmptyList, ChatServers) ->
        {server, Pid, Reference,LoggedInUsers} = dict:fetch(Key,ChatServers),
        LoggedInUsers < 100,
        {server, Pid, Reference,LoggedInUsers};
    
    get_chat_server(NonEmptyList, ChatServers) ->        
        get_chat_server(T, ChatServers).
    

    因此,第一个子句将始终匹配第二个子句匹配的任何内容。更具体地说,在模式中:

    [Key|_]
    

    Key 将匹配任何内容,_ 将匹配任何内容。同样,在模式中:

    [_|T]
    

    _ 将匹配任何内容,T 将匹配任何内容。

    模仿@dsmith 的回答:

    -module(my).
    -export([get_chat_server/3, get_chat_server_test/0]).
    
    get_chat_server(_MaxLoggedIn, []=_Keys, _ChatServers) ->        
        none;
    get_chat_server(MaxLoggedIn, [Key|Keys], ChatServers) ->
        get_chat_server(MaxLoggedIn, Keys, ChatServers, dict:fetch(Key, ChatServers) ).
    
    get_chat_server(MaxLoggedIn, _, _, {_,_,_,LoggedInUsers}=ChatServer) when LoggedInUsers < MaxLoggedIn ->
        ChatServer;
    get_chat_server(MaxLoggedIn, [Key|Keys], ChatServers, _ChatServer) ->
        get_chat_server(MaxLoggedIn, Keys, ChatServers, dict:fetch(Key, ChatServers) ).
    
    %---------
    
    get_chat_server_test() ->
        Keys = [a, c],
        ChatServers = [
             {a, {server, a, a_, 200}},
             {b, {server, b, b_, 100}},
             {c, {server, c, c_, 30}}
        ],  
        ChatServerDict = dict:from_list(ChatServers),
    
        none = get_chat_server(10, [], ChatServerDict),
        {server, c, c_, 30} = get_chat_server(50, Keys, ChatServerDict),
        {server, c, c_, 30} = get_chat_server(150, Keys, ChatServerDict),
        PossibleResults = sets:from_list([{server,a,a_, 200},{server,c,c_,30}]),
        true = sets:is_element(
                 get_chat_server(250, Keys, ChatServerDict),
                 PossibleResults
               ),
        all_tests_passed.      
    

    您还可以使用高阶函数,即dict:fold(),来获取满足您要求的所有聊天服务器的列表:

    max_fun(Max, Keys) ->
        fun(Key, {_,_,_,LoggedInUsers}=Server, Acc) ->
                case lists:member(Key, Keys) andalso LoggedInUsers<Max of
                    true -> [Server | Acc];
                    false -> Acc
                end
        end.
    

    在外壳中:

    44>     ChatServers = [
    44>          {a, {server, a, a_, 200}},
    44>          {b, {server, b, b_, 100}},
    44>          {c, {server, c, c_, 30}}
    44>     ].
    [{a,{server,a,a_,200}},
     {b,{server,b,b_,100}},
     {c,{server,c,c_,30}}]
    
    45> ChatServerDict = dict:from_list(ChatServers).
    {dict,3,16,16,8,80,48,
          {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
          {{[],
            [[a|{server,a,a_,200}]],
            [[b|{server,b,b_,100}]],
            [[c|{server,c,c_,30}]],
            [],[],[],[],[],[],[],[],[],[],[],[]}}}
    
    46> Keys = [a,c].
    [a,c]
    
    47> MaxLoggedIn = 150.
    150
    
    50> F = my:max_fun(MaxLoggedIn, Keys).
    #Fun<fl.0.128553666>
    
    51> dict:fold(F, [], ChatServerDict).
    [{server,c,c_,30}]
    

    【讨论】:

      【解决方案2】:

      你可以做这样的事情......

         get_chat_server([], _) ->        
             undefined;
      
         get_chat_server([Key|T], ChatServers) ->
             {server, Pid, Reference,LoggedInUsers} = dict:fetch(Key,ChatServers),
             if
                LoggedInUsers < 100 -> 
                    {server, Pid, Reference,LoggedInUsers};
                true -> 
                    get_chat_server(T, ChatServers)
             end.
      

      或者这个

         get_chat_server([], _) ->        
             undefined;
      
         get_chat_server([Key|T], ChatServers) ->
             Result = dict:fetch(Key,ChatServers),
             case Result of
                {_, _, _, LoggedInUsers} when LoggedInUsers < 100 ->
                   Result;
                _ -> 
                   get_chat_server(T, ChatServers)
             end.
      

      【讨论】:

        【解决方案3】:

        子句的主体(-&gt; 右侧的所有内容)不是要满足的条件列表,而只是要评估的以逗号分隔的表达式列表。除了最后一个表达式的结果值之外的所有结果值都将被丢弃。因此,&lt; 比较的布尔值不会在任何地方使用。

        【讨论】:

          猜你喜欢
          • 2016-11-08
          • 1970-01-01
          • 2021-03-26
          • 2015-01-05
          • 2016-05-06
          • 1970-01-01
          • 2021-01-24
          • 2020-07-25
          • 2015-03-06
          相关资源
          最近更新 更多