Perché questo lavoro:Julia macro splatting
function test_func(a, b)
a + b
end
test_func((1, 2)...)
Ma questo non lo fa?
macro test_func(a, b)
a + b
end
@test_func((1, 2)...)
È un bug in Julia?
Perché questo lavoro:Julia macro splatting
function test_func(a, b)
a + b
end
test_func((1, 2)...)
Ma questo non lo fa?
macro test_func(a, b)
a + b
end
@test_func((1, 2)...)
È un bug in Julia?
Macro operano sulla sintassi di superficie , pertanto @test_func
non visualizza il risultato dello splat. Invece, vede l'operazione di splat stessa! Come sempre, un ottimo modo per controllare questo è di citare e vedere esattamente ciò che sintassi della macro è in funzione il:
julia> :(@test_func((1,2)...))
:(@test_func (1,2)...)
julia> Meta.show_sexpr(ans)
(:macrocall, symbol("@test_func"), (:..., (:tuple, 1, 2)))
Quindi la macro sta ricevendo un argomento (non due), ed è un Expr(:..., Expr(:tuple, 1, 2))
. Si noti che la tupla (1,2) è passata alla macro, ma è nascosta all'interno dell'operazione di splat. Così si potrebbe scavare nel Expr
e tipo-di-tipo-di implementare Splatting te stesso:
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
Ma questo solo tipo-di-tipo-di supporti splatting. Guardate cosa succede se si tenta di operare su una variabile invece:
julia> @test_func(xs...)
ERROR: unsupported syntax (:(xs...),)
ora non c'è alcun modo per la macro per sapere quello che dovrebbe essere l'aggiunta insieme!