Elixir元编程编译流程疑问:代码输出顺序为何是BBB hh in BBB AAA
嘿,这个问题刚好戳中Elixir编译和执行时机的关键点,我来给你掰扯清楚为什么输出顺序是BBB → hh in BBB → AAA~
先把你的代码贴出来方便对照:
defmodule BBB do IO.puts "BBB" defmacro hh do IO.puts "hh in BBB" end end defmodule AAA do IO.puts "AAA" require BBB BBB.hh end
核心原因:Elixir的「编译时操作」和「运行时操作」是分开的
Elixir处理模块代码时,会把编译时要做的事和运行时才做的事拆成两个阶段执行,这就是你看到顺序“反常”的关键。
第一步:处理BBB模块
当解释器/编译器遇到defmodule BBB时,会直接按顺序执行模块内的顶层代码(不在def/defmacro里的代码):
- 首先执行
IO.puts "BBB",所以第一个输出是BBB。 - 然后定义宏
hh——这只是把宏的代码存起来,宏内部的IO.puts "hh in BBB"此时不会执行,因为宏是编译时调用的,只有当它被调用时才会触发执行。
第二步:处理AAA模块
处理defmodule AAA时,Elixir会优先处理所有编译时指令,再执行运行时的顶层代码:
- 先处理编译时操作:
- 看到
require BBB:这是编译时指令,确保BBB模块已经被编译(这里已经完成了)。 - 看到
BBB.hh:因为hh是用defmacro定义的宏,所以这是一个编译时调用——此时会立即执行宏内部的代码IO.puts "hh in BBB",输出第二个内容hh in BBB。
- 看到
- 再执行运行时顶层代码:
所有编译时操作完成后,才会执行模块里的IO.puts "AAA",输出第三个内容AAA。
这样整个顺序就完全对应上你看到的输出啦!
内容的提问来源于stack exchange,提问作者chenyuandong
相关产品推荐
相关产品推荐

