我刚刚开始学习长生不老药中的宏。我目前正在阅读元编程长生不老药的书。
在本书的开头,有一个如何创建一个名为say的宏的示例。此宏将采用类似 5 + 5
的表达式并返回一串"5 plus 5 is 10"
...
defmacro say({:+, _, [lhs, rhs]}) do
quote do
lhs = unquote(lhs)
rhs = unquote(rhs)
result = lhs + rhs
IO.puts "#{lhs} plus #{rhs} is #{result}"
result
end
end
我想知道为什么我们在定义自己的宏时需要使用quote
和unquote
宏?
defmacro say({:+, _, [lhs, rhs]}) do
result = lhs * rhs
IO.puts "#{lhs} plus #{rhs} is #{result}"
result
end
宏的第二个版本不会返回完全相同的答案吗?
我对宏的工作方式有什么误解吗?
宏
应该返回AST。AST 将直接注入到调用宏的位置。这将在编译阶段发生。
也就是说,后者将评估乘法的结果,在编译阶段将消息放在stdout
,并注入一个表示结果的常量来代替宏调用。此宏仅接受编译时常量,它不接受例如变量:
say(5 + 5) # works
with foo <- 5, do: say(foo + 5) # raises
前者将产生实际的 AST 进行评估。