在解构 AoT (Array of Tuple) 时发现, 当 AoT 里不是 NTuple
时会导致 getindex
的类型推断出现问题, 但使用 map
却可以推断出类型. 下面是我运行的代码:
当 AoT 里是 NTuple
时, getindex
和 map
都可以正确推断出类型
julia> a = [(1, 2) (3, 4)];
julia> a isa Array{T} where T <: Tuple, a isa Array{NTuple{N, E}} where {N, E}
(true, true)
julia> @code_warntype getindex.(a, 1)
MethodInstance for (::var"##dotfunction#308#171")(::Matrix{Tuple{Int64, Int64}}, ::Int64)
from (::var"##dotfunction#308#171")(x1, x2) in Main
Arguments
#self#::Core.Const(var"##dotfunction#308#171"())
x1::Matrix{Tuple{Int64, Int64}}
x2::Int64
Body::Matrix{Int64}
1 ─ %1 = Base.broadcasted(Main.getindex, x1, x2)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2}, Nothing, typeof(getindex), Tuple{Matrix{Tuple{Int64, Int64}}, Int64}}
│ %2 = Base.materialize(%1)::Matrix{Int64}
└── return %2
julia> @code_warntype map(ele->ele[1], a)
MethodInstance for map(::var"#169#170", ::Matrix{Tuple{Int64, Int64}})
from map(f, A::AbstractArray) in Base at abstractarray.jl:2867
Arguments
#self#::Core.Const(map)
f::Core.Const(var"#169#170"())
A::Matrix{Tuple{Int64, Int64}}
Body::Matrix{Int64}
1 ─ %1 = Base.Generator(f, A)::Base.Generator{Matrix{Tuple{Int64, Int64}}, var"#169#170"}
│ %2 = Base.collect_similar(A, %1)::Matrix{Int64}
└── return %2
但是 AoT 里不是 NTuple
会出现:
julia> b = [(1, 0.2) (3, 0.4)];
julia> b isa Array{T} where T <: Tuple, b isa Array{NTuple{N, E}} where {N, E}
(true, false)
julia> @code_warntype getindex.(b, 1)
MethodInstance for (::var"##dotfunction#309#172")(::Matrix{Tuple{Int64, Float64}}, ::Int64)
from (::var"##dotfunction#309#172")(x1, x2) in Main
Arguments
#self#::Core.Const(var"##dotfunction#309#172"())
x1::Matrix{Tuple{Int64, Float64}}
x2::Int64
Body::Union{Matrix{Float64}, Matrix{Int64}, Matrix{Real}}
1 ─ %1 = Base.broadcasted(Main.getindex, x1, x2)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{2}, Nothing, typeof(getindex), Tuple{Matrix{Tuple{Int64, Float64}}, Int64}}
│ %2 = Base.materialize(%1)::Union{Matrix{Float64}, Matrix{Int64}, Matrix{Real}}
└── return %2
julia> @code_warntype map(ele->ele[1], b)
MethodInstance for map(::var"#173#174", ::Matrix{Tuple{Int64, Float64}})
from map(f, A::AbstractArray) in Base at abstractarray.jl:2867
Arguments
#self#::Core.Const(map)
f::Core.Const(var"#173#174"())
A::Matrix{Tuple{Int64, Float64}}
Body::Matrix{Int64}
1 ─ %1 = Base.Generator(f, A)::Base.Generator{Matrix{Tuple{Int64, Float64}}, var"#173#174"}
│ %2 = Base.collect_similar(A, %1)::Matrix{Int64}
└── return %2
上面的 @code_warntype getindex.(b, 1)
显示返回类型的不稳定的.
这是 julia 自身的问题吗? 我最近在跟 CUDA ~打胶~打交道, 类型不稳定的话甚至不能运行, 如果可以的话希望可以使得 getindex
在这种情况下保持类型稳定.