Elixir 宏 - 作为变量传递的参数的模式匹配
Elixir macros - pattern match on an argument passed as a variable
我试图更好地理解 Elixir 宏,但我无法弄清楚如何设置一个场景,在该场景中我可以模式匹配我传递给宏的参数,当我的值是m 试图通过是一个变量。这里有一个简单的例子来说明:
macro_test.ex
defmodule MacroTest do
use MacroTest.UseMe
def run() do
atom = :hello_world
macro_a(atom)
end
end
use_me.ex
defmodule MacroTest.UseMe do
defmacro __using__(_) do
quote do
defmacro macro_a(:hello_world) do
quote do
"Success!"
end
end
defmacro macro_a(:some_other_atom) do
quote do
"Did something else..."
end
end
end
end
end
当我尝试编译这段代码时,出现错误
== Compilation error in file lib/macro_test.ex ==
** (FunctionClauseError) no function clause matching in MacroTest.macro_a/1
如果我改变最初的run()
函数,让原子直接传递给宏,比如macro_a(:hello_world)
,那么它compiles/runs就好了。
我如何改变这种情况,以便宏可以对作为变量提供的值进行模式匹配,而不是文字值本身?
这取决于你想做什么。在编译时宏 运行,并对部分源代码进行操作(与上述源代码返回的 运行 时间值相反)。所以在这种情况下,宏知道它已被一个名为 atom
的变量调用,但它无法知道该变量已在调用函数的前面分配给
您可以在 运行 时间检查给定变量的值:
defmacro macro_a(a) do
quote do
case unquote(a) do
:hello_world ->
"Success!"
:some_other_atom ->
"Did something else..."
end
end
end
也就是说,每次调用 macro_a
都会被上面的 case
表达式替换,使用传递的任何变量或其他表达式作为参数。
我试图更好地理解 Elixir 宏,但我无法弄清楚如何设置一个场景,在该场景中我可以模式匹配我传递给宏的参数,当我的值是m 试图通过是一个变量。这里有一个简单的例子来说明:
macro_test.ex
defmodule MacroTest do
use MacroTest.UseMe
def run() do
atom = :hello_world
macro_a(atom)
end
end
use_me.ex
defmodule MacroTest.UseMe do
defmacro __using__(_) do
quote do
defmacro macro_a(:hello_world) do
quote do
"Success!"
end
end
defmacro macro_a(:some_other_atom) do
quote do
"Did something else..."
end
end
end
end
end
当我尝试编译这段代码时,出现错误
== Compilation error in file lib/macro_test.ex ==
** (FunctionClauseError) no function clause matching in MacroTest.macro_a/1
如果我改变最初的run()
函数,让原子直接传递给宏,比如macro_a(:hello_world)
,那么它compiles/runs就好了。
我如何改变这种情况,以便宏可以对作为变量提供的值进行模式匹配,而不是文字值本身?
这取决于你想做什么。在编译时宏 运行,并对部分源代码进行操作(与上述源代码返回的 运行 时间值相反)。所以在这种情况下,宏知道它已被一个名为 atom
的变量调用,但它无法知道该变量已在调用函数的前面分配给
您可以在 运行 时间检查给定变量的值:
defmacro macro_a(a) do
quote do
case unquote(a) do
:hello_world ->
"Success!"
:some_other_atom ->
"Did something else..."
end
end
end
也就是说,每次调用 macro_a
都会被上面的 case
表达式替换,使用传递的任何变量或其他表达式作为参数。