0

在阅读 Erlang 和 OTP 的实际操作时,我遇到了一些奇怪的语法,这些语法与我难以理解的记录有关。我希望有人可以在这里澄清句柄信息中发生的超时情况:

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)
4

2 回答 2

2

请记住,Erlang 中的“赋值”是模式匹配。在您的问题中给出的上下文中,

#state{lsock = LSock} = State

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

于 2015-05-20T21:06:38.350 回答
2

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

#state{lsock = LSock} = State

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

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

请注意,匹配表达式在匹配时返回 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
于 2015-05-21T08:34:54.807 回答