繁体   English   中英

Elixir 宏:如何定义具有动态数量的函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM