我有一个Union{Type1, Type2, Type3}
,它与类型为那些类型之一的所有值匹配。但是我该如何匹配类型本身?
MyU = Union{Float64, Int, Array}
a::MyU = 3.5 # works
a = 5 # works
a = [1, 2, 3] # works
# but of course
a = Float64 # nope
a = Int # nope
a = Array # nope
对于普通类型,通常可以通过Type{MyType}
来实现,其唯一值为MyType
。但是Type{MyU}
仅匹配MyU
,而不匹配它包含的类型。我该如何匹配?
我当然可以只使用DataType
,但这有两个问题:
Array
。我目前的解决方法是Union{DataType,UnionAll}
,但是如果我在Union
中包含另一个MyU
或其他一些非混凝土类型,那么这是一个丑陋的hack,它必然会崩溃并烧毁。 / p>
我的另一个解决方案是像这样建立第二个并行Union:
MyU = Union{Float64, Int, Array}
MyUT = Union{Type{Float64}, Type{Int}, Type{Array}}
它确实可以工作并且更加严格,但是它也很丑陋,并且通过手动保持人与人之间的同步来引入人为错误的可能性很大。
答案 0 :(得分:2)
您可以考虑采用以下方法来避免使用宏(这可能会很棘手):
gettypes(u::Union) = [u.a; gettypes(u.b)]
gettypes(u) = [u]
typewrap(u) = Union{[Type{v} for v in gettypes(u)]...}
然后:
julia> MyU = Union{Float64, Int, Array}
Union{Float64, Int64, Array}
julia> MyUT = typewrap(MyU)
Union{Type{Array}, Type{Float64}, Type{Int64}}
编辑
作为附加说明,您可以像这样将gettypes
定义为一个衬纸:
gettypes(u) = u isa Union ? [u.a; gettypes(u.b)] : [u]
编辑2
或更简单,没有中间数组:
typewrap(u) = u isa Union ? Union{Type{u.a}, typewrap(u.b)} : Type{u}