gen_server handle_info/2 说明

gen_server handle_info/2 clarification

在阅读 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)

记住,Erlang 中的"assignment" 是模式匹配。在您问题中给出的上下文中,

#state{lsock = LSock} = State

断言 State 绑定到 #state{} 记录的值,同时它将 LSock 变量绑定到 lsock State 的字段。

所有函数参数定义都是模式,和

#state{lsock = LSock} = State

一个模式,它将State绑定到作为函数调用参数传递的整个术语,同时断言它是一个记录状态并绑定State#state.lsock 到 LSock。在您的 shell 示例中,

A = 1.
1 = A.

匹配表达式,其形式为

<pattern> = <expression>

因此,您只能在“=”的左侧引入和绑定新变量。对于演示模式内等号匹配的示例,您可以 运行 在 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

注意匹配表达式 returns 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