>我对我的宏有以下定义
defmacro defverified(sign, body) do
{name, _, [param]} = sign
quote do
def unquote(name)(unquote(param)) do
unquote(param) = verify! param
unquote(body)
end
end
end
如果verify!/1
被验证为正确的参数,则返回其参数
我的函数定义如下
defverified toto(p) do
IO.inspect p
end
并且检查p
的内容是正确的,但函数的返回是我的变量的引用形式。
iex(3)> res = Toto.toto(1)
1
[do: 1]
iex(4)> res
[do: 1]
是否可以使用不带引号的形式来返回我的函数,或者我应该手动取消引号?
我希望我的函数的以下输出
iex(3)> res = Toto.toto(1)
1
1
iex(4)> res
1
发生这种情况是因为do
...end
结构是一种特殊的句法糖。 例如,这个:
def toto(p) do
IO.inspect p
end
相当于:
def toto(p), do: IO.inspect p
由于参数末尾的关键字作为关键字列表传递,因此等效于:
def(toto(p), [do: IO.inspect(p)])
由于您的defverified
宏只需要一个do
块,而不需要其他关键字参数,因此我们可以显式匹配实际正文:
defmacro defverified(sign, [do: body]) do
...
在执行此操作之前,toto
函数中的最后一个形式实际上是:
[do: IO.inspect param]
这将按预期调用IO.inspect
,但随后返回关键字列表而不是纯值。