Syntax 发电机服务器处理信息/2澄清
在阅读Erlang和OTP的过程中,我遇到了一些关于记录的奇怪语法,这让我很难理解。我希望有人能澄清这里超时的句柄信息中发生了什么: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 +
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两次!