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变体。