![](/img/trans.png)
[英]Macro expansion in elixir: how to define 2 macros with one using the other?
[英]Elixir macros: how to define function with dynamic arity
请参阅这篇文章: 如何使用 Elixir 宏创建动态函数名称? .
上面的帖子问了如何使用宏生成不带参数的函数,但我想知道如何生成带参数的函数?
假设有一个宏warp
,我可以编写如下代码:
warp fun, [args], :ok
然后它生成如下代码:
fun(args), do: :ok
如果要生成动态参数列表,则需要使用unquote_splicing
,如下所示:
defmacro warp(name, argument_names, code) do
quote do
def unquote(name)(unquote_splicing(argument_names)) do
unquote(code)
end
end
end
后来:
warp :foo, [a, b], {:ok, a, b}
它产生:
def foo(a, b), do: {:ok, a, b}
如果你调用它会产生:
foo(1, 2)
# {:ok, 1, 2}
您也可以像这样定义宏而不使用unquote_splicing
并将组合的名称和参数传递给def
:
defmacro warp(name_and_args, do: code) do
quote do
def unquote(name_and_args) do
unquote(code)
end
end
end
这意味着您需要像调用def
一样调用warp
,例如:
warp foo(a, b), do: {:ok, a, b}
这是一个非常简单的例子:
defmodule SomeMacro do
defmacro warp(name, status) do
quote do
def unquote(name)(args) do
{unquote(status), Enum.join(args, " - ")}
end
end
end
end
defmodule SomeModule do
require SomeMacro
SomeMacro.warp :something, :ok
end
如果你像这样在 IEX 中运行它:
iex(1)> SomeModule.something([1,2,3])
{:ok, "1 - 2 - 3"}
iex(2)> SomeModule.something(["one", "two", "three"])
{:ok, "one - two - three"}
👍
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.