defmodule DemoMacro do
defmacro i_am_macro do
quote do
# ……
end
end
i_am_macro # (CompileError) example.exs:10: undefined function i_am_macro/0
end
但是从其他模块导入,可以成功调用:
defmodule SecondModule do
require DemoMacro
DemoMacro.i_am_macro
end
我应该怎么做才能让第一段代码通过?
最佳答案
您从模块主体调用宏,意思是在编译阶段。在编译阶段,这个模块的内容显然是不可访问的,因为模块还没有编译。
将宏移动到一个函数中:
defmodule DemoMacro do
defmacro i_am_macro do
quote do
IO.puts "Inside a macro"
end
end
def test_macro(), do: i_am_macro()
end
DemoMacro.test_macro()
#⇒ "Inside a macro"
宏内容是一个 AST,在每次宏调用时被注入(inject)到位。在编译阶段,您可能会使用已经编译的 Elixir 代码。理解编译阶段和运行时之间的区别需要一点心理转变,主要是因为在这两个阶段我们使用相同的 Elixir 语法。但事情是 Elixir,作为一种编译语言,除非它被编译成 BEAM,否则不能使用代码。
您也可以在 @after_compile
中使用您的宏回调,在编译阶段,在模块 BEAM 可用(已编译)后立即:
defmodule DemoMacro do
defmacro i_am_macro do
quote do
IO.puts "Inside a macro"
end
end
@after_compile __MODULE__
def __after_compile__(env, _bytecode) do
i_am_macro()
end
end
#⇒ immediately prints "Inside a macro"
关于elixir - 关于在模块内调用宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51632346/