macros - 宏块意外返回 [do: return value]
问题描述
我在宏中有以下定义:
defmacro route(pattern, options \\ [], block) do
name = "my_fun"
def unquote(name)(var!(conn)) do
unquote(block)
end
end
我用这个函数调用宏:
route "/" do
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
内部块返回一个%Plug.Conn{}
结构,但是当我在宏中打印结果时unquote(block)
,我得到[do: %Plug.Conn{}]
了我在做什么错?关键字do
列表从何而来?
更大的片段
defmacro route(pattern, options \\ [], block) do
name = Keyword.get_lazy(options, :name, fn -> create_name(pattern, options) end)
route = {pattern, name}
quote do
@routes [unquote(route) | @routes]
def unquote(name)(var!(conn)) do
resp = unquote(block)
IO.puts("outside the block, resp is")
IO.inspect(resp)
end
end
end
route "/" do
resp = conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
IO.puts("Inside the block, resp is")
IO.inspect(resp)
resp
end
结果
Inside the block, resp is
%Plug.Conn{
adapter: {Plug.Adapters.Cowboy2.Conn, :...},
assigns: %{},
{....SNIP....}
}
outside the block, resp is
[
do: %Plug.Conn{
adapter: {Plug.Adapters.Cowboy2.Conn, :...},
assigns: %{},
{....SNIP....}
}
]
解决方案
您需要将参数从更改block
为do: block
:
defmacro route(pattern, options \\ [], do: block) do
Elixir 宏调用中的do ... end
参数作为单项关键字列表传递,键为:do
.
如果您不通过将它的模式匹配为 来删除该嵌套do: block
,则参数的值将是[do: block]
,当您取消引用它时,您将取消引用[do: ...]
,这也是一个有效的表达式,并解释了您的代码工作的原因以及打印的原因[do: ...]
。
推荐阅读
- list - Xamarin.Android:在运行时更改列表中的特定值
- excel - Excel 宏刷新数据然后格式化单元格
- powershell - Exit and Continue 脚本(例如获取PATH环境改变效果)
- php - Buddypress groups_create_group 未定义
- tfs - 将集合从 TFS 2015 迁移到 TFS 2018
- c# - 通过 sender 参数访问后台工作程序
- python - 比较 2 个 CSV 文件并将一个文件中的值添加到另一个匹配项
- oxyplot - Xamarin Forms WPF项目中的OxyPlot,如何更改跟踪器文本颜色
- javascript - 重写reduce方法js的问题
- angular - Nativescript + Angular ScrollView 滚动到最终监听器