鉴于这一守则:
defmodule MyModule do
def my_func(<< part::binary-size(size), rest::binary >>, size) do
IO.puts(part)
end
def my_func_2(size, << part::binary-size(size), rest::binary >>) do
IO.puts(part)
end
def my_func_3(size, << part::binary-size(size-1), rest::binary >>) do
IO.puts(part)
end
end模块不会编译。如果我注释掉除一个以外的所有函数,我会得到不同的错误:
my_func/1进行编译会给出以下错误:
警告:变量" size“不存在,并且正在展开为"size()",请使用括号消除歧义或更改变量名my_script.exs:2 ** (CompileError) my_script.exs:2:位字符串中的大小需要整数或变量作为参数,got: size() ()(长生不老药)src/elixir_bitstr.src:52::elixir_bitstr.elixir_bit_info/5(长生不老药)src/elixir_bitstr.src:29::elixir_bitstr.lists.erl:1354_bitstr/4 (elixir) src/elixir_bitstr.src:10::elixir_bitstr.展开(stdlib)my_func_2/1编译会给我带来另一个错误:
** (CompileError) my_script.exs:6:变量大小@1未绑定(stdlib) lists.erl:1338::lists.foreach/2 (stdlib) erl_eval.erl:670::erl_val.do_apply/6my_func_3/1编译会给我一个不同的错误:
** (CompileError) my_script.exs:10:按位字符串表示的大小需要一个整数或一个变量作为参数,got::erlang。-( size,1) (长生不老药)src/长生不老药_bitstr.src:52::elixir_bitstr. lists.erl:1354::lists.mapfoldl/3 (stdlib) lists.erl:1355::lists.mapfoldl/3 (stdlib)能给我解释一下所有的错误吗?在erlang编译器级别发生了什么?为什么?
发布于 2016-07-13 22:00:22
Erlang和Elixir欺骗了我们,使我们相信我们可以在每个数据结构上进行嵌套模式匹配,但是二进制文件是一个例外。这里你可以读到
二进制模式不能嵌套(.)段具有以下一般语法:
Value:Size/TypeSpecifierList当匹配Value时,值必须是变量或整数,或浮点文字。不允许使用表达式。 大小必须是整数文本,或以前绑定的变量。不允许采取以下措施: foo(N,<) -> {X,T}。 N的两次出现不相关。编译器会抱怨size字段中的N没有绑定。 编写此示例的正确方法如下: foo(N,Bin) -> <>= Bin,{X,T}。
这也适用于灵丹妙药。
因此,在my_func中,编译不尝试在第一个参数之后查看函数头,并表示没有名为size的变量。它估计它可能是一个函数,然后编译器会出现一个错误,上面写着size in bitstring expects an integer or a variable as argument。
在my_func_2中,事情变得很棘手,因为变量在第一个参数中,但它还没有绑定。这正是上述Erlang文档的情况。你不能在尺寸上匹配图案。它必须是以前绑定的变量。名称size@1提示您,编译器并不将这两个变量视为相同的变量。他们内部有不同的名字。
在my_func_3编译器中,可以看到有一个减法,所以它不会费心检查变量,并立即报告不能在二进制模式匹配中使用表达式。
解决这个限制的正确方法也在引用的部分中。
https://stackoverflow.com/questions/38361466
复制相似问题