为何Elixir中允许<< "Halo" >>却禁止<< String.reverse("Halo") >>?
为什么<< String.reverse("Halo") >>会抛出ArgumentError?
这个问题的核心其实是Elixir二进制字面量(<< ... >>)的语法规则限制,我来给你一步步讲清楚:
先看为什么<< "Halo" >>合法
"Halo"在Elixir里本身就是一个二进制(binary)类型的值,而<< ... >>作为二进制字面量语法,允许直接嵌入已经是二进制/位串类型的字面量——这是编译器支持的语法糖,它能直接识别并处理这个字面量,所以不会报错。
再看为什么<< String.reverse("Halo") >>不行
String.reverse("Halo")是一个运行时函数调用,而Elixir的<< ... >>语法对内部允许的内容有严格限制:它只能接受以下几类元素:
- 整数(可以配合位规格指定位宽,比如
<< 72 :: size(8) >>) - 二进制/位串类型的字面量或变量
- 符合
表达式 :: 位规格格式的位语法表达式
编译器在解析<< ... >>的时候,不会去执行一个函数调用并把结果嵌入到二进制字面量里——它期望的是编译时就能确定结构的元素,或者符合位语法规则的构造,而不是任意的运行时计算结果。
正确的做法
如果你想用函数调用的结果构造二进制,只需要先把结果存到变量里,再放入<< ... >>即可:
iex> reversed = String.reverse("Halo") "olaH" iex> << reversed >> "olaH"
这样变量reversed指向的是二进制值,完全符合<< ... >>的语法要求,就不会报错了。
内容的提问来源于stack exchange,提问作者Andree
相关产品推荐
相关产品推荐

