为什么Elixir指南说要在宏定义中使用引号和取消引号

时间:2019-02-07 14:46:24

标签: int elixir metaprogramming

我刚刚开始了解e剂中的宏。我目前正在阅读metaprogramming-elixir书。

在本书的开头,有一个示例,说明如何创建一个名为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

我想知道为什么在定义自己的宏时需要使用quoteunquote宏吗?

defmacro say({:+, _, [lhs, rhs]}) do
  result = lhs * rhs
  IO.puts "#{lhs} plus #{rhs} is #{result}"
  result
end

第二个版本的宏不会返回完全相同的答案吗?

我对宏的工作方式有误解吗?

1 个答案:

答案 0 :(得分:1)

宏应该返回AST。 AST将直接注入到调用宏的位置。这将在编译阶段中发生。

也就是说,后者将评估相乘的结果,在编译阶段将消息放入stdout ,并注入代表结果的常量来代替宏调用。此宏将仅接受编译时常量,而不接受例如变量:

say(5 + 5)                       # works
with foo <- 5, do: say(foo + 5)  # raises

前者将为评估生成实际的AST。