kel*_*ogs 0 erlang arguments list operators
Run Code Online (Sandbox Code Playgroud)** Reason for termination = ** {badarg,[{erlang,'++',[<<>>,"</after></set></query></iq>"]}, {geoloc,get_nearby,1},
方法是:
get_nearby({_Pid, DynVars})->
%Last = ts_dynvars:lookup(last, DynVars),
Last = lists:keysearch(last,1,DynVars),
{ok, Rad} = ts_dynvars:lookup(rad,DynVars),
{ok, Lat} = ts_dynvars:lookup(lat,DynVars),
{ok, Lon} = ts_dynvars:lookup(lon,DynVars),
if is_tuple(Last) ->
{value,{Key,After}} = Last,
if length(After) == 0 ->
After2 = "0";
true ->
After2 = After
end,
"<iq id=\"" ++ common:get_random_string(5,"abcdefghijklmnopqrstuvwxyz0123456789-+=") ++ "\" xmlns=\"http://xmpp.xgate.com.hk/plugins\" to=\"xmpp.xgate.hk.com\" type=\"get\"><query xmlns=\"jabber:iq:geoloc\"><geoloc><lat>" ++ Lat ++ "</lat><lon>" ++ Lon ++ "</lon><radius>" ++ Rad ++ "</radius></geoloc><set xmlns=\"http://jabber.org/protocol/rsm\"><max>" ++ integer_to_list(ran_max()) ++ "</max><after>" ++ After2 ++ "</after></set></query></iq>";
true -> % Last is boolean, namely the 'false' atom
ts_dynvars:set([rad, lat, lon], [Rad, Lat, Lon], DynVars),
"<iq id=\"" ++ common:get_random_string(5,"abcdefghijklmnopqrstuvwxyz0123456789-+=") ++ "\" xmlns=\"http://xmpp.xgate.com.hk/plugins\" to=\"xmpp.xgate.hk.com\" type=\"get\"><query xmlns=\"jabber:iq:geoloc\"><geoloc><lat>" ++ Lat ++ "</lat><lon>" ++ Lon ++ "</lon><radius>" ++ Rad ++ "</radius></geoloc><set xmlns=\"http://jabber.org/protocol/rsm\"><max>" ++ integer_to_list(ran_max()) ++ "</max></set></query></iq>"
end.
Run Code Online (Sandbox Code Playgroud)
您正在尝试连接binary(<<>>)和字符串,但++只能连接两个字符串(或列表 - Erlang字符串实际上是列表).
这意味着它After2是二进制文件,因此它在if表达式的第二个子句中接收到此值.通常length(After)在After不是列表时调用会导致badarg异常,但是当它出现在if测试中时,它被视为保护测试,异常被忽略,因此length(After) == 0被视为false.所以当你进入它时,相应的值已经是二进制了DynVars.
一些建议:
要检查列表是否为空,调用length它有点浪费,因为length需要遍历整个列表.相反,写下这样的东西:
case After of
"" ->
After2 = "0";
[_|_] ->
After2 = After
end
Run Code Online (Sandbox Code Playgroud)
[_|_]是一种匹配非空列表的模式.在您的情况下,值After不会与任何子句匹配,并且您有一个case_clause错误,告诉您实际获得的值.
当然,如果您真的希望在这里使用二进制文件,请检查<<>>并<<_/binary>>改为使用.
你在++那里做了很多连接().在表达式中A ++ B,++运算符需要沿着整个列表行走A,因此运行时间与长度成正比A.
连接有两种常见的替代方法.首先,通常会消耗结果的函数实际上并不需要一个平面列表,但对"深度列表"或"iolist"同样满意 - 而不是"foo" ++ "bar"写["foo", "bar"].值得注意的是,如果您要将结果写入文件或将其发送到套接字,则两者都接受file:write并同时gen_tcp:send接受这两种变体.
其次,您可以使用二进制代替字符串.二进制文件在许多有趣的方面与字符串不同(至少它们在垃圾收集方面的表现如何),但它们确实具有可以有效连接的良好属性.如果是A和B二进制文件,并且你编写C = <<A/binary, B/binary>>,并且编译器可以看到你只使用C但不是A之后,B将简单地连接到持有的内存区域A.有关详细信息,请参阅"效率指南"中有关二元处理的章节.
开头的两条线"<iq id=\""几乎相同,只是第一条插入"<after>" ++ After2 ++ "</after>"中间.您可以设置第一个case子句MaybeAfter = "<after>" ++ After2 ++ "</after>"和第二个case子句MaybeAfter = "",然后使用一行MaybeAfter在正确的位置插入值.这将有助于使代码更具可读性.
| 归档时间: |
|
| 查看次数: |
215 次 |
| 最近记录: |