Elixir构建bitstring时指定已有bitstring大小触发ArgumentError
Elixir bitstring指定size触发ArgumentError的原因解析
我在做Exercism的Elixir题目《variable-length-quantity》时,尝试从bitstring提取7位数据,在字节开头添加标记位后拼接到累加器bitstring头部,遇到了一个困惑的问题:给已有的bitstring指定size时会触发无明确提示的ArgumentError。
示例代码如下:
iex(28)> a = <<64::size(7)>> <<64::size(7)>> iex(29)> b = <<1::size(1)>> <<1::size(1)>> iex(30)> <<b::size(1), a::size(7)>> ** (ArgumentError) argument error while evaluating iex at line 30 (stdlib 4.0) eval_bits.erl:143: :eval_bits.eval_exp_field/6 (stdlib 4.0) eval_bits.erl:77: :eval_bits.create_binary/2 (stdlib 4.0) eval_bits.erl:68: :eval_bits.expr_grp/5 (stdlib 4.0) erl_eval.erl:543: :erl_eval.expr/6 (iex 1.13.4) lib/iex/evaluator.ex:310: IEx.Evaluator.handle_eval/3 iex(30)> # 当然,这样写是正常工作的 iex(30)> <<b::bitstring, a::bitstring>> <<192>>
为什么不能为已有的bitstring指定size?
- Elixir的bitstring构造语法里,
::size(n)是用来定义新bitstring段的长度,而非验证已有bitstring的长度。当你写<<b::size(1)>>时,语法期望b是整数或可解析为原始位数据的类型,而非已经存在的bitstring。 - 若要验证已有bitstring的长度,需手动检查:比如用
bit_size(b) == 1判断,不符合时抛出明确错误,不能在bitstring构造语法中通过指定size来实现。
错误信息不友好的原因
- 该错误来自Erlang底层的
eval_bits模块,Elixir直接传递了Erlang的原始错误信息。Erlang底层模块通常不提供面向应用层的友好提示,因为默认调用者熟悉底层语法规则。 - 这类错误属于语法规则误用,
eval_bits模块未针对此场景做专门的错误信息优化,因此仅返回通用的"argument error"。
内容的提问来源于stack exchange,提问作者jim
相关产品推荐
相关产品推荐

