Macros Elixir宏:如何用动态算术定义函数
请参阅此帖子: 上面的帖子问如何使用宏生成没有参数的函数,但我想知道如何生成带有一些参数的函数 假设有一个宏Macros Elixir宏:如何用动态算术定义函数,macros,elixir,Macros,Elixir,请参阅此帖子: 上面的帖子问如何使用宏生成没有参数的函数,但我想知道如何生成带有一些参数的函数 假设有一个宏warp,我可以编写如下代码: warp fun, [args], :ok fun(args), do: :ok 然后生成如下代码: warp fun, [args], :ok fun(args), do: :ok 下面是一个非常简单的示例: defmodule SomeMacro do defmacro warp(name, status) do quote do
warp
,我可以编写如下代码:
warp fun, [args], :ok
fun(args), do: :ok
然后生成如下代码:
warp fun, [args], :ok
fun(args), do: :ok
下面是一个非常简单的示例:
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"}
defmacro warp(name, argument_names, code) do
quote do
def unquote(name)(unquote_splicing(argument_names)) do
unquote(code)
end
end
end
如果要生成参数的动态列表,需要使用以下命令:
iex(1)> SomeModule.something([1,2,3])
{:ok, "1 - 2 - 3"}
iex(2)> SomeModule.something(["one", "two", "three"])
{:ok, "one - two - three"}
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\u拼接
,只需将组合名称和参数传递给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}
我很难找到关于“unquote\u拼接”的文档。标题的改变可能会对像我这样的未来谷歌人有所帮助。这是一个非常酷、非常好的回答。但是,如果我们真的想像调用def(您的最后一行)一样调用它,而不是在一行代码中
,DO:*1-line-only*
表单(aka:warp-foo(a,b)DO…end
)无需担心。我很肯定它会“起作用”。如果我理解正确,Elixir将接受,do:…
或do。。。结束
版本完全相同。对于这个令人敬畏的答案@Bukov yep,这只是语法,sugar和Elixir很乐意接受这两种变体。谢谢你的客气话