Syntax 发电机服务器处理信息/2澄清

Syntax 发电机服务器处理信息/2澄清,syntax,erlang,gen-server,Syntax,Erlang,Gen Server,在阅读Erlang和OTP的过程中,我遇到了一些关于记录的奇怪语法,这让我很难理解。我希望有人能澄清这里超时的句柄信息中发生了什么: handle_info({tcp, Socket, RawData}, State) -> do_rpc(Socket, RawData), RequestCount = State#state.request_count, {noreply, State#state{request_count = RequestCount +

在阅读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
这似乎是某种反向赋值?你是说第二个参数将是一个#状态记录,将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中的“赋值”是模式匹配。根据你问题中给出的上下文

#state{lsock = LSock} = State
断言
State
绑定到一个
#State{}
记录的值,同时将
LSock
变量绑定到
State

LSock
字段的值记住,Erlang中的“赋值”是模式匹配。根据你问题中给出的上下文

#state{lsock = LSock} = State

断言
State
绑定到一个值,该值是
#State{}
记录,同时它将
LSock
变量绑定到
State
LSock
字段的值。所有函数参数定义都是模式,并且

是一种模式,它将状态绑定到作为函数调用参数传递的整个项,同时声明它是记录状态,并将状态#State.lsock绑定到lsock。在shell示例中

A = 1.
1 = A.
是匹配表达式,其形式为

<pattern> = <expression>
另一方面,你的例子

test:test_assignment({1,2},{3,4}).
引发arror,因为在您定义的函数子句中,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
10>4=C。
*1:变量“C”未绑定
11> C=4。
4.
%4=4,因此匹配并返回4:
12> 4=C。
4.
%现在C是绑定的,所以这是一个匹配4=5,而不是=5:
13> C=5。
**异常错误:右侧值5不匹配

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

是一种模式,它将状态绑定到作为函数调用参数传递的整个项,同时声明它是记录状态,并将状态#State.lsock绑定到lsock。在shell示例中

A = 1.
1 = A.
是匹配表达式,其形式为

<pattern> = <expression>
另一方面,你的例子

test:test_assignment({1,2},{3,4}).
引发arror,因为在您定义的函数子句中,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
10>4=C。
*1:变量“C”未绑定
11> C=4。
4.
%4=4,因此匹配并返回4:
12> 4=C。
4.
%现在C是绑定的,所以这是一个匹配4=5,而不是=5:
13> C=5。
**异常错误:右侧值5不匹配

我想我还没有在模式匹配的右侧看到未绑定的赋值。我希望它是这样的:
State=#State{lsock=lsock}
记住函数的参数已经绑定好了。因此,该代码将
State
参数与
#State{}
记录构造相匹配,同时执行
LSock
绑定。你可以任意编写(试试!),但根据我的经验,这种顺序更常用于参数。因此,我在shell中尝试了未绑定变量的逆序赋值,但它不起作用<代码>2>1=A.*1:变量“A”未绑定3>A=1。1 4> {1,2}. {1,2}5>{1,2}=B.*1:变量“B”未绑定,因为您试图匹配未绑定的变量,所以该变量无效。正如我前面提到的,函数参数总是已经绑定的,这就是我的“您可以任意编写”注释的上下文。在shell中试试这个例子:
1>F=fun(1=A)->A;(A=2)->A*2;(A) ->A*3结束。
注意
A
如何在前两个子句中按任意顺序匹配,然后
2>{F(1),F(2),F(3)}。
将返回
{1,4,9}
。我想我还没有看到模式匹配右侧的未绑定赋值。我希望它是这样的:
State=#State{lsock=lsock}
记住函数的参数已经绑定好了。因此,该代码将
State
参数与
#State{}
记录构造相匹配,同时执行
LSock
绑定。你可以任意编写(试试!),但根据我的经验,这种顺序更常用于参数。因此,我在shell中尝试了未绑定变量的逆序赋值,但它不起作用<代码>2>1=A.*1:变量“A”未绑定3>A=1。1 4> {1,2}. {1,2}5>{1,2}=B.*1:变量“B”未绑定,因为您试图匹配未绑定的变量,所以该变量无效。正如我前面提到的,函数参数总是已经绑定的,这就是我的“您可以任意编写”注释的上下文。在shell中试试这个例子:
1>F=fun(1=A)->A;(A=2)->A*2;(A) ->A*3结束。
注意
A
在前两个子句中是如何按任意顺序匹配的,然后
2>{F(1),F(2),F(3)}。
将返回
{1,4,9}
。啊,这现在有意义了。我也没有意识到我用了X两次!啊,这是有道理的。我也没有意识到我用了X两次!