Julia 朱莉娅宏喷溅

Julia 朱莉娅宏喷溅,julia,Julia,为什么这样做有效: function test_func(a, b) a + b end test_func((1, 2)...) 但事实并非如此 macro test_func(a, b) a + b end @test_func((1, 2)...) 这是Julia中的错误吗?宏在表面语法上运行,因此@test\u func看不到splat的结果。相反,它看到的是splat操作本身!与往常一样,检查这一点的一个很好的方法是引用它,并查看宏操作的语法: julia> :(

为什么这样做有效:

function test_func(a, b)
  a + b
end

test_func((1, 2)...)
但事实并非如此

macro test_func(a, b)
  a + b
end

@test_func((1, 2)...)

这是Julia中的错误吗?

宏在表面语法上运行,因此
@test\u func
看不到splat的结果。相反,它看到的是splat操作本身!与往常一样,检查这一点的一个很好的方法是引用它,并查看宏操作的语法:

julia> :(@test_func((1,2)...))
:(@test_func (1,2)...)

julia> Meta.show_sexpr(ans)
(:macrocall, symbol("@test_func"), (:..., (:tuple, 1, 2)))
因此宏只接收一个参数(不是两个),它是一个
Expr(:…,Expr(:tuple,1,2))
。请注意,元组(1,2)正在传递给宏,但它只是隐藏在splat操作中。因此,您可以深入研究
Expr
,并自行开发某种工具:

julia> macro test_func(as...)
           if length(as) == 1 && isa(as[1], Expr) && as[1].head == :... &&
                  isa(as[1].args[1], Expr) && as[1].args[1].head == :tuple
               a, b = as[1].args[1].args
           elseif length(as) == 2
               a, b = as
           else
               error("unsupported syntax $as")
           end
           return esc(:($a + $b))
       end

julia> @test_func((1,2)...)
3
但这是唯一一种支持喷溅的方式。看看如果您尝试对变量进行操作会发生什么:

julia> @test_func(xs...)
ERROR: unsupported syntax (:(xs...),)

现在宏无法知道应该添加什么

“现在宏无法知道它应该加在一起什么!”这句话真的帮助了我。谢谢