在阅读Erlang和OTP的过程中,我遇到了一些关于记录的奇怪语法,我无法绕过脑袋。我希望有人能在这里澄清handle_info中的超时情况:
handle_info({tcp, Socket, RawData}, State) ->
do_rpc(Socket, RawData),
RequestCount = State#state.request_count,
{noreply, State#state{request_count = RequestCount + 1}};
handle_info(timeout, #state{lsock = LSock} = State) ->
{ok, _Sock} = gen_tcp:accept(LSock),
{noreply, State}.
具体来说,我不太清楚这里发生了什么:
#state{lsok = LSock} = State
这似乎是某种反向分配?你是否有效地说第二个参数是#state记录,将lsock值赋给LSock变量并将整个记录分配给State?我只是根据变量在接下来的两行中的使用情况来推断,但这种语法看起来很奇怪。
[编辑]
我在shell中对模式匹配和赋值进行了一些测试,并且它没有像我预期的那样工作:
2> 1 = A.
* 1: variable 'A' is unbound
3> A = 1.
1
4> {1,2}.
{1,2}
5> {1,2} = B.
* 1: variable 'B' is unbound
然后我运行了这个测试函数,看看它是否只是匹配函数参数:
test_assignment(A = {X,Y},{W,X} = B) ->
io:format("Variable A is ~p~n",[A]),
io:format("Variable B is ~p~n",[B]).
24> c(test).
test.erl:21: Warning: variable 'W' is unused
test.erl:21: Warning: variable 'Y' is unused
{ok,test}
25> test:test_assignment({1,2},{3,4}).
** exception error: no function clause matching test:test_assignment({1,2},{3,4}) (test.erl, line 21)
答案 0 :(得分:2)
请记住,Erlang中的“赋值”是模式匹配。在您的问题中给出的上下文中,
#state{lsock = LSock} = State
断言State
绑定到#state{}
记录的值,同时将LSock
变量绑定到lsock
字段的值State
。
答案 1 :(得分:2)
所有函数参数定义都是模式和
#state{lsock = LSock} = State
是一个模式,它将State绑定到作为函数调用参数传递的整个术语,同时声明它是一个记录状态并将State#state.lsock绑定到LSock。在你的shell示例中,
A = 1.
1 = A.
是匹配表达式,其格式为
<pattern> = <expression>
因此,您可以仅在&#34; =&#34;的左侧引入和绑定新变量。有关在模式中使用等号匹配的示例,您可以在erlang shell中轻松运行:
1> ({X,Y} = Z) = {1,2}.
{1,2}
2> X.
1
3> Y.
2
4> Z.
{1,2}
另一方面,你的例子是
test:test_assignment({1,2},{3,4}).
引发了一个恐怖,因为在函数子句中你定义的X在模式{X,Y},{Z,X}中使用了两次,它们无法匹配参数,显然1不等于4.你可以在shell中尝试:
5> TestAssignment = fun (A = {X, Y}, {W, X} = B) ->
5> io:format("Variable A is ~p~n", [A]),
5> io:format("Variable B is ~p~n", [B]) end.
6> TestAssignment ({1,2}, {3,4}).
** exception error: no function clause matching erl_eval:'-inside-an-interpreted-fun-'({1,2},{3,4})
7> TestAssignment ({1,2}, {3,1}).
Variable A is {1,2}
Variable B is {3,1}
ok
请注意,匹配表达式在匹配时返回rhs表达式。你现在应该明白,为什么它的工作方式如下:
10> 4 = C.
* 1: variable 'C' is unbound
11> C = 4.
4
% 4 = 4, so this matches and returns 4:
12> 4 = C.
4
% now C is bound, so this is a match 4 = 5, not <anything, that will be bound to C> = 5:
13> C = 5.
** exception error: no match of right hand side value 5