问题描述
例如,我想编写一个可以转换的宏@macro1
transform(df,@macro :X :Y)
至
transform(df,(:X,:Y)...)
这是我的尝试
macro macro1(ex...)
println(ex)
:($ex...)
end
transform(df,@macro1 :X :Y)
这似乎很难。但是,如果允许宏像这样在外面
@macro transform(df,(:X :Y))
然后更容易。但是我不确定“内部”宏样式是否可以实现这一目标。
解决方法
我猜您是想让它与逗号一起使用吗?
julia> macro splicing(expr)
return Expr(:(...),esc(expr))
end
@splicing (macro with 1 method)
julia> @macroexpand tuple(:w,@splicing :x,:y)
:(tuple(:w,(:x,:y)...))
julia> tuple(:w,:y)
(:w,:x,:y)
最微妙的部分是语法@m a,b
被解析为@m((a,b))
。我们可以直接将其包装到拼接调用中。
不要在实际的varargs上尝试此操作,但是可能会发生令人讨厌的堆栈溢出。
对于大小为1的输入,您可能需要特殊的情况,因为这不会构造元组:
julia> tuple(:w,@splicing :x)
ERROR: MethodError: no method matching iterate(::Symbol)
Closest candidates are:
iterate(::Core.SimpleVector) at essentials.jl:600
iterate(::Core.SimpleVector,::Any) at essentials.jl:600
iterate(::ExponentialBackOff) at error.jl:218
...
Stacktrace:
[1] top-level scope at REPL[34]:1
以下方法可能有效,但可能会变得脆弱:
macro splicing3(expr)
if Meta.isexpr(expr,:tuple)
return Expr(:(...),esc(expr))
else
return esc(expr)
end
end