首页 > 解决方案 > 在 Julia 中将 DataType 转换为 UnionAll

问题描述

是否可以在 a 中释放 aTypeVarDataType获得 a UnionAll

大局,我想做的是:

# this doesnt work
f(::Type{V{T}}, ::Type{S}) where {T,S,V<:AbstractVector} = V{S} 

f(Vector{Int}, Char) 
# Vector{Char}

我目前的解决方案是@eval f(::Type{$(V){T}}, S::Type)手动创建类型列表V <: AbstractVector,但我希望有一个更直接的解决方案

标签: typesjulia

解决方案


您可以尝试这种方法:

function f(::Type{V}, ::Type{S}) where {V<:AbstractVector{T}, S} where T
    s = Core.Compiler.unwrap_unionall(V.name.wrapper)
    v = s.super
    while v.name.wrapper != AbstractArray
        v = v.super
    end
    loc = findfirst(==(v.parameters[1]), s.parameters)
    V.name.wrapper{V.parameters[1:loc-1]...,S,V.parameters[loc+1:end]...}
end

现在:

julia> f(Vector{Int}, Char)
Array{Char,1}

julia> f(UnitRange{Int}, Float64)
UnitRange{Float64}

julia> abstract type MyType1{A,B,C} <: AbstractVector{B} end

julia> struct MyType2{P,Q,R,S} <: MyType1{R,Q,S} end

julia> f(MyType2{Int, Int, Int, Int}, Char)
MyType2{Int64,Char,Int64,Int64}

请注意,您的方法@eval并不完全通用,并且不会处理复杂的自定义子类型AbstractVector(如示例中的最后一个)。


推荐阅读