Elixir多子句函数首行无函数体全匹配def声明有何作用
这个无函数体的首行是Elixir的函数头(Function Header)语法,属于编译阶段生效的声明,不是运行时参与匹配的全匹配子句,核心作用如下:
- 明确函数的公共签名:它提前声明
infinity_binary是接收1个参数的公开函数,后续所有同名def都是这个函数的匹配分支,读代码的人不用翻完所有子句,就能快速知道这个函数的参数个数。 - 规避多子句定义的低级错误:Elixir是按「函数名+参数元数(参数个数)」区分不同函数的,如果没有这个头声明,后续写子句时万一多写、少写了参数,会悄无声息定义出一个全新的同名不同元数的函数,不会触发任何提示;有了函数头约束之后,只要后续子句的参数个数和头声明不一致,编译器会直接抛编译错误,把问题拦在编译阶段。
- 减少冗余代码:如果要给函数加类型标注、文档说明、默认参数,只需要在函数头上写一次即可,不用给每个具体匹配子句重复编写,既省代码,也能避免不同子句的标注内容不一致。
注意:这个函数头完全不参与运行时的参数匹配,也不是兜底分支。如果传入的参数不满足后续4个浮点类型元组的匹配规则,依然会正常抛出
FunctionClauseError,不会因为这行声明就匹配成功。
涉及的示例代码如下:
def infinity_binary(type) def infinity_binary({:bf, 16}), do: <<0x7F80::16-native>> def infinity_binary({:f, 16}), do: <<0x7C00::16-native>> def infinity_binary({:f, 32}), do: <<0x7F800000::32-native>> def infinity_binary({:f, 64}), do: <<0x7FF0000000000000::64-native>>
这种写法在子句较多、代码维护周期长的项目里非常常见,尤其是Nx这类对类型一致性要求极高的基础库,用函数头能大幅降低维护时的出错概率。
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

