在 Elixir 中引用函数名
Quote function name in Elixir
我现在正在学习 Elixir,我对 quote
和 unquote
真的很困惑。
以下是我们如何使用 macro
:
创建具有动态名称的函数
defmacro create_fun(n) do
quote do: def unquote(:"times_#{n}")(a), do: a * 4
end
它创建函数 times_6
,例如,如果我将 6
作为宏参数传递。
现在我不明白的是: 这里我们取消引用原子 :"times_#{n}"
。 Elixir 文档说当你引用一个原子时它 returns 一个原子。所以当我取消引用一个原子时,我也应该取回这个原子。这是真的:
iex(15)> Macro.to_string quote do: unquote(:"times_6")
":times_6"
但是在引号后立即使用 ()
给出了这个:
iex(14)> Macro.to_string quote do: unquote(:"times_6")()
"times_6()"
带括号的原子突然变成了非原子。如果我用 :"times_6"
替换 unquote(:"times_6")
它不起作用:
iex(4)> Macro.to_string quote do: :"times_6"()
** (SyntaxError) iex:4: syntax error before: '('
拜托,这是怎么回事,我不明白
这就是 quote
和 unquote
在 Elixir 中的实现方式
来自Elixir Metaprogramming Guide:
The building block of an Elixir program is a tuple with three
elements. For example, the function call sum(1, 2, 3)
is represented
internally as:
iex> quote do: sum(1, 2, 3)
{:sum, [], [1, 2, 3]}
The first element is the function name, the second is a keyword list
containing metadata and the third is the arguments list.
模块和方法名称在 elixir 中内部表示为 atoms
。直接查看调用 unquote(:"hello")
和 unquote(:"hello")()
时生成的基础 elixir 数据可能有助于解决这个问题:
iex(27)> quote do: unquote(:"hello")
:hello
iex(28)> quote do: unquote(:"hello")()
{:hello, [], []}
第一个只是returns一个原子,而第二个returns一个Elixir数据结构(一个由3个元素组成的元组)代表一个使用 0 个参数调用 hello
方法。 unquote(:"hello")()
转换为 hello()
然后用作方法。
我现在正在学习 Elixir,我对 quote
和 unquote
真的很困惑。
以下是我们如何使用 macro
:
defmacro create_fun(n) do
quote do: def unquote(:"times_#{n}")(a), do: a * 4
end
它创建函数 times_6
,例如,如果我将 6
作为宏参数传递。
现在我不明白的是: 这里我们取消引用原子 :"times_#{n}"
。 Elixir 文档说当你引用一个原子时它 returns 一个原子。所以当我取消引用一个原子时,我也应该取回这个原子。这是真的:
iex(15)> Macro.to_string quote do: unquote(:"times_6")
":times_6"
但是在引号后立即使用 ()
给出了这个:
iex(14)> Macro.to_string quote do: unquote(:"times_6")()
"times_6()"
带括号的原子突然变成了非原子。如果我用 :"times_6"
替换 unquote(:"times_6")
它不起作用:
iex(4)> Macro.to_string quote do: :"times_6"()
** (SyntaxError) iex:4: syntax error before: '('
拜托,这是怎么回事,我不明白
这就是 quote
和 unquote
在 Elixir 中的实现方式
来自Elixir Metaprogramming Guide:
The building block of an Elixir program is a tuple with three elements. For example, the function call
sum(1, 2, 3)
is represented internally as:iex> quote do: sum(1, 2, 3) {:sum, [], [1, 2, 3]}
The first element is the function name, the second is a keyword list containing metadata and the third is the arguments list.
模块和方法名称在 elixir 中内部表示为 atoms
。直接查看调用 unquote(:"hello")
和 unquote(:"hello")()
时生成的基础 elixir 数据可能有助于解决这个问题:
iex(27)> quote do: unquote(:"hello")
:hello
iex(28)> quote do: unquote(:"hello")()
{:hello, [], []}
第一个只是returns一个原子,而第二个returns一个Elixir数据结构(一个由3个元素组成的元组)代表一个使用 0 个参数调用 hello
方法。 unquote(:"hello")()
转换为 hello()
然后用作方法。