【发布时间】:2018-01-24 00:59:39
【问题描述】:
所以我使用的是 Phoenix 1.3,我创建了一个宏来生成一个函数并将其注入到控制器中。
根据我传入的数字,我希望它生成一个映射,其中包含许多名为“id1”、“id2”等的参数,一直到“id#{number}”。此映射将与通常的 Phoenix "conn" 一起成为参数列表的一部分。
所以我想生成一个这样的方法来进行模式匹配并且可以执行“一些东西”:
def index(conn, %{"id1" => id1, "id2" => id2}) do
# some stuff
end
当我调用宏create_some_function_by_number("index", 2).
我的宏看起来像:
defmacro create_some_function_by_number(name, num) do
params =
for n <- 1..num, do: %{"id#{n}" => Macro.var(:"id#{n}", nil)}
|> Map.new
quote do
def unquote(:"#{name}")(unquote(Macro.escape(params)) do
# some code here for the index action
end
end
end
1) 如何将“conn”注入函数头,以便进行模式匹配?
2) 这是创建要进行模式匹配的地图的正确方法吗?
【问题讨论】:
-
使用宏听起来像是过早的优化。你能通过迭代 params 映射中的元组来解决你的问题吗?
-
@J.RandomCoder - 您是否有链接或 sn-p 或有关“迭代参数映射中的元组”的进一步详细信息?
-
另外,我还想了解更多关于元编程的知识,所以我想知道这个问题的答案?符合这一点。
-
我的意思是你可以在运行时动态地对映射中的“项目”(元组)的数量做出反应,而不是在编译时为任何有意义的参数数量定义函数。无论第一个参数中有多少元组,以下 sn-p 都将起作用:
Enum.map(%{"id1": 23, "id2": 42}, fn {key,value} -> IO.puts("#{key}: #{value}") end). -
我希望在函数头上进行精确的模式匹配,因为这似乎也可以让我更轻松地利用 action_fallback 进行错误处理。所以如果不匹配
def some_dynamic_fund(conn, %{"id1" => id1, "id2" => id2} = params), do: "hello",那么自然会回退到错误中。
标签: macros elixir phoenix-framework