Julia 朱莉娅:有没有可能把'fn(df,@macro1:a,:b,:c)`转换成'fn(df,(:a,:b,:c)…)`
例如,我想编写一个宏Julia 朱莉娅:有没有可能把'fn(df,@macro1:a,:b,:c)`转换成'fn(df,(:a,:b,:c)…)`,julia,metaprogramming,Julia,Metaprogramming,例如,我想编写一个宏@macro1,用于转换 转换(df,@macro:X:Y)到 变换(df,(:X,:Y)…) 这是我的尝试 macro macro1(ex...) println(ex) :($ex...) end transform(df, @macro1 :X :Y) 这似乎很难。但是,如果允许宏像这样位于外部 @宏转换(df,(:X:Y)) 那就容易多了。但是我不确定“内部”宏样式是否可以实现这一点。我想你是想让它使用逗号吧 julia> macro spl
@macro1
,用于转换
转换(df,@macro:X:Y)
到
变换(df,(:X,:Y)…)
这是我的尝试
macro macro1(ex...)
println(ex)
:($ex...)
end
transform(df, @macro1 :X :Y)
这似乎很难。但是,如果允许宏像这样位于外部
@宏转换(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, @splicing :x, :y)
(:w, :x, :y)
微妙之处在于语法@ma,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
但这有什么意义?这是更复杂的事情的一部分吗?是的。更复杂的请看我的编辑。以前的版本只是在这个特殊测试用例中意外地起作用:我认为您必须避免varargs变体。