Erlang:变量是未绑定的

Erl*_*abe 5 erlang

为什么以下说变量未绑定?

9> {<<A:Length/binary, Rest/binary>>, Length} = {<<1,2,3,4,5>>, 3}.     
* 1: variable 'Length' is unbound
Run Code Online (Sandbox Code Playgroud)

很明显Length应该是3.

我试图有一个类似模式匹配的功能,即:

parse(<<Body:Length/binary, Rest/binary>>, Length) ->
Run Code Online (Sandbox Code Playgroud)

但如果失败的原因相同.如何实现我想要的模式匹配?


我真正想要实现的是将传入的tcp流包解析为LTV(长度,类型,值).

在我解析长度和类型后的某个时刻,我想只准备多达Length字节数作为值,因为其余的可能是下一个LTV.

所以我的parse_value功能是这样的:

parse_value(Value0, Left, Callback = {Module, Function},
       {length, Length, type, Type, value, Value1}) when byte_size(Value0) >= Left ->
    <<Value2:Left/binary, Rest/binary>> = Value0,
    Module:Function({length, Length, type, Type, value, lists:reverse([Value2 | Value1])}),
    if 
    Rest =:= <<>> ->
        {?MODULE, parse, {}};
    true ->
        parse(Rest, Callback, {})
    end;
parse_value(Value0, Left, _, {length, Length, type, Type, value, Value1}) ->
    {?MODULE, parse_value, Left - byte_size(Value0), {length, Length, type, Type, value, [Value0 | Value1]}}.
Run Code Online (Sandbox Code Playgroud)

如果我可以进行模式匹配,我可以把它分解成更令人愉悦的东西.

Ric*_*rdC 6

模式匹配的规则是,如果变量X出现在两个子模式中,如{X,X}或{X,[X]}或类似,则它们必须在两个位置具有相同的值,但是每个子模式的匹配仍然在相同的输入环境中完成 - 来自一侧的绑定不会转移到另一侧.之后在概念上进行等式检查,就好像你在{X,X2}上匹配并添加了一个保护X =:= X2.这意味着元组中的Length字段不能用作二进制模式的输入,即使您将其作为最左边的元素也是如此.

但是,二进制模式中,字段中绑定的变量可以在其后的其他字段中使用,从左到右.因此,以下工作(使用二进制中的前导32位大小字段):

1> <<Length:32, A:Length/binary, Rest/binary>> = <<0,0,0,3,1,2,3,4,5>>.
<<0,0,0,3,1,2,3,4,5>>
2> A.
<<1,2,3>>
3> Rest.                                                               
<<4,5>>
Run Code Online (Sandbox Code Playgroud)