警告:使用运算符“<”无效?
Warning: use of operator '<' has no effect?
我是 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: Warning: use of operator '<' has no
effect main_server_distributed.erl:66: Warning: this clause cannot
match because a previous clause at line 61 always matches
我对 prolog 有一些经验,据我所知,这是对模式匹配和递归的有效使用。你能指出我在这里做错了什么吗?提前致谢。
子句的主体(->
右侧的所有内容)不是要满足的条件列表,而只是要计算的以逗号分隔的表达式列表。除最后一个表达式之外的所有结果值都将被丢弃。因此,您的 <
比较的布尔值未在任何地方使用。
main_server_distributed.erl:66: Warning: this clause cannot match
because a previous clause at line 61 always matches
你基本上写了:
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(),来获取满足您要求的所有 ChatServers 的列表:
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.
在shell:
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}]
你可以这样做...
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.
我是 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: Warning: use of operator '<' has no effect main_server_distributed.erl:66: Warning: this clause cannot match because a previous clause at line 61 always matches
我对 prolog 有一些经验,据我所知,这是对模式匹配和递归的有效使用。你能指出我在这里做错了什么吗?提前致谢。
子句的主体(->
右侧的所有内容)不是要满足的条件列表,而只是要计算的以逗号分隔的表达式列表。除最后一个表达式之外的所有结果值都将被丢弃。因此,您的 <
比较的布尔值未在任何地方使用。
main_server_distributed.erl:66: Warning: this clause cannot match because a previous clause at line 61 always matches
你基本上写了:
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(),来获取满足您要求的所有 ChatServers 的列表:
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.
在shell:
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}]
你可以这样做...
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.