Elixir调用函数时何时需要在模块名前添加冒号“:”?
iex(5)> IO.puts("hello world") hello world :ok iex(6)> :math.exp(3) 20.085536923187668
写法差异原因
这个差异来自Elixir和Erlang同跑在BEAM虚拟机上的生态特性,两种写法对应两类完全不同来源的模块:
- 不带冒号的
IO是原生Elixir模块:这类模块用Elixir语法编写,遵循Elixir大写驼峰的模块命名规范,Elixir对这类模块做了语法糖封装,调用时直接写模块名即可,不需要额外加前缀。Elixir标准库中的String、Enum、Map都属于这类模块。 - 带冒号的
:math是原生Erlang模块:这类模块是Erlang生态(包括Erlang标准库、第三方Erlang库)的模块,命名规则是全小写的原子类型,Elixir没有对这类模块做语法糖适配,必须按照Erlang原子的语法规则,在模块名前加冒号才能正常调用。Erlang标准库中的:lists、:proplists、:erlang调用时都需要加冒号。
加冒号的判断规则
调用模块时是否需要在名称前加冒号,判断标准非常明确:
- 调用Elixir编写的、大写驼峰命名的模块时,不需要加冒号,直接写模块名调用即可
- 调用Erlang编写的、全小写原子命名的模块时,必须在模块名前加冒号才能调用
补充个底层逻辑方便理解:Elixir中所有模块名本质都是原子,Elixir原生模块IO对应的底层原子实际是:"Elixir.IO"。当你写IO.puts时,Elixir编译器会自动把大写开头的驼峰模块名转换成对应带Elixir.前缀的原子,省去了手动写冒号和前缀的步骤,你甚至可以直接写:"Elixir.IO".puts("test")执行,运行效果和IO.puts完全一致,只是日常开发不会用这种冗余写法。
内容的提问来源于stack exchange,提问作者Chen Yu
相关产品推荐
相关产品推荐

