我对宏有以下定义
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
答案 0 :(得分:2)
之所以会这样,是因为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
,但随后返回关键字列表而不是简单值。