为什么长生不老药指南说要在宏定义中使用引号和取消引号
Why do elixir guides say to use quote and unquote inside of a macro definition
我刚刚开始学习 elixir 中的宏。我目前正在阅读 metaprogramming-elixir 一书。
本书的开头有一个示例,说明如何创建名为 say 的宏。该宏将采用 5 + 5
和 return 之类的表达式 "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
宏的第二个版本 return 不是完全相同的答案吗?
我对宏的工作方式有什么误解吗?
宏应该 return AST。 AST 将被直接注入到调用宏的地方。这将发生在编译阶段。
也就是说,后者会计算乘法的结果,在编译阶段将消息传递给stdout
并注入一个常量,代表结果,在宏调用的地方。这个宏只接受编译时常量,它不会接受例如变量:
say(5 + 5) # works
with foo <- 5, do: say(foo + 5) # raises
前者将为求值生成实际的AST。
我刚刚开始学习 elixir 中的宏。我目前正在阅读 metaprogramming-elixir 一书。
本书的开头有一个示例,说明如何创建名为 say 的宏。该宏将采用 5 + 5
和 return 之类的表达式 "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
宏的第二个版本 return 不是完全相同的答案吗?
我对宏的工作方式有什么误解吗?
宏应该 return AST。 AST 将被直接注入到调用宏的地方。这将发生在编译阶段。
也就是说,后者会计算乘法的结果,在编译阶段将消息传递给stdout
并注入一个常量,代表结果,在宏调用的地方。这个宏只接受编译时常量,它不会接受例如变量:
say(5 + 5) # works
with foo <- 5, do: say(foo + 5) # raises
前者将为求值生成实际的AST。