朱莉娅宏喷溅

bra*_*ayl 9 julia

为什么这样做:

function test_func(a, b)
  a + b
end

test_func((1, 2)...)
Run Code Online (Sandbox Code Playgroud)

但这不是吗?

macro test_func(a, b)
  a + b
end

@test_func((1, 2)...)
Run Code Online (Sandbox Code Playgroud)

这是朱莉娅的一个错误吗?

Mat*_* B. 12

宏在表面语法上运行,因此@test_func没有看到splat的结果.相反,它看到了splat操作本身!与往常一样,检查它的一个好方法是引用它并查看宏正在运行的语法:

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

julia> Meta.show_sexpr(ans)
(:macrocall, symbol("@test_func"), (:..., (:tuple, 1, 2)))
Run Code Online (Sandbox Code Playgroud)

所以宏只接收一个参数(而不是两个),它是一个Expr(:..., Expr(:tuple, 1, 2)).请注意,元组(1,2)获取传递到您的宏,但它只是隐藏在图示的操作中.因此,您可以深入了解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
Run Code Online (Sandbox Code Playgroud)

但这只是一种支持splatting的类型.看看如果你尝试操作变量会发生什么:

julia> @test_func(xs...)
ERROR: unsupported syntax (:(xs...),)
Run Code Online (Sandbox Code Playgroud)

宏现在还没有办法知道它应该加在一起的是什么!