Methods 在Julia中的并集类型上操作
在Julia中,Methods 在Julia中的并集类型上操作,methods,types,julia,dispatch,union-types,Methods,Types,Julia,Dispatch,Union Types,在Julia中,isimmutable函数可以告诉您对象何时是不可变的。但是,它不适用于类型,所以我想为类型编写一个版本。根据我在别处找到的建议,一个好的开端是: isimmtype(t::Type) = error("Type $t has not defined isimmtype") isimmtype(t::DataType) = begin if !t.isconcretetype error("Abstract types are neither immuta
isimmutable
函数可以告诉您对象何时是不可变的。但是,它不适用于类型,所以我想为类型编写一个版本。根据我在别处找到的建议,一个好的开端是:
isimmtype(t::Type) = error("Type $t has not defined isimmtype")
isimmtype(t::DataType) = begin
if !t.isconcretetype
error("Abstract types are neither immutable nor mutable")
else
return !t.mutable
end
end
这很有用,并且回答了许多但不是所有类型的问题。到目前为止,我注意到的故障分为两类:
Union
和UnionAll
类型。两者似乎都有简单的解决方案。在UnionAll
的情况下,我们可以使用类型变量的上限对类型的具体化进行测试。对于Union{a,B}
,我们可以比较a
和B
类型的可变性,并推断Union的可变性"""
Mutability
The Mutability type is an abstract trait type with children Mutable, Immutable,
and UnknownMutability.
"""
abstract type Mutability end
struct Mutable <: Mutability end
struct Immutable <: Mutability end
struct UnknownMutability <: Mutability end
const MUT_TYPE = Mutable()
const IMM_TYPE = Immutable()
const UNK_TYPE = UnknownMutability()
"""
mutability(obj)
Yields an object of type Mutable, Immutable, or UnknownMutability depending on
whether the given type object is mutable, immutable, or unknown.
"""
mutability(T::Type) = UNK_TYPE
isimmtype(T::Type) = IMM_TYPE === mutability(T)
mutability(T::DataType) = begin
if !T.isconcretetype
return UNK_TYPE
elseif T.mutable
return MUT_TYPE
else
return IMM_TYPE
end
end
mutability(::Core.TypeofBottom) = UNK_TYPE
mutability(T::UnionAll) = mutability(T{T.var.ub})
mutability(::Type{String}) = IMM_TYPE
mutability(::Type{Symbol}) = IMM_TYPE
# This one causes problems:
mutability(::Type{Union{A,B}}) where {A,B} = begin
let mA=mutability(A), mB=mutability(B)
if mA === UNK_TYPE || mB === UNK_TYPE || mA !== mB
return UNK_TYPE
else
return mA
end
end
end
“”“
易变性
可变性类型是一种抽象的特质类型,其子代是可变的、不可变的,
和不可知的可改变性。
"""
抽象类型可变端
struct Mutable自从发布问题以来,我意识到一个可能的答案是在默认方法中显式测试Union
类型:
mutability(T::Type) = begin
if typeof(T) !== Union
return UNK_TYPE
else
let mA=mutability(T.a), mB=mutability(T.b)
if mA === UNK_TYPE || mB === UNK_TYPE || mA !== mB
return UNK_TYPE
else
return mA
end
end
end
end
使用上述其他方法,可正确进行以下所有测试:
map(k->k=>(mutability(k), isimmtype(k)),
[String, Symbol, Int64,
Dict{Int64,String}, Array, Array{Int64,1},
Tuple, Tuple{}, Tuple{Int64,String,Symbol},
Union{String,Symbol}, Union{String,Array}, Union{Array,Dict}])
#12元素数组{对,1}:
#字符串=>(不可变(),true)
#Symbol=>(不可变(),true)
#Int64=>(不可变(),true)
#Dict{Int64,String}=>(可变(),false)
#数组=>(可变(),false)
#数组{Int64,1}=>(可变(),false)
#Tuple=>(UnknownMutability(),false)
#元组{}=>(不可变(),true)
#元组{Int64,String,Symbol}=>(不可变(),true)
#联合{String,Symbol}=>(不可变(),true)
#联合{String,Array}=>(UnknownMutability(),false)
#联合{Dict,Array}=>(可变(),false)
#
所有这些在我看来都是正确的。然而,我仍然想知道是否有其他解决方案在Union
上显式匹配,以及是否有其他实例中这些函数无法正确检测可变性 发布问题后,我意识到一个可能的答案是在默认方法中显式测试Union
类型:
mutability(T::Type) = begin
if typeof(T) !== Union
return UNK_TYPE
else
let mA=mutability(T.a), mB=mutability(T.b)
if mA === UNK_TYPE || mB === UNK_TYPE || mA !== mB
return UNK_TYPE
else
return mA
end
end
end
end
使用上述其他方法,可正确进行以下所有测试:
map(k->k=>(mutability(k), isimmtype(k)),
[String, Symbol, Int64,
Dict{Int64,String}, Array, Array{Int64,1},
Tuple, Tuple{}, Tuple{Int64,String,Symbol},
Union{String,Symbol}, Union{String,Array}, Union{Array,Dict}])
#12元素数组{对,1}:
#字符串=>(不可变(),true)
#Symbol=>(不可变(),true)
#Int64=>(不可变(),true)
#Dict{Int64,String}=>(可变(),false)
#数组=>(可变(),false)
#数组{Int64,1}=>(可变(),false)
#Tuple=>(UnknownMutability(),false)
#元组{}=>(不可变(),true)
#元组{Int64,String,Symbol}=>(不可变(),true)
#联合{String,Symbol}=>(不可变(),true)
#联合{String,Array}=>(UnknownMutability(),false)
#联合{Dict,Array}=>(可变(),false)
#
所有这些在我看来都是正确的。然而,我仍然想知道是否有其他解决方案在Union
上显式匹配,以及是否有其他实例中这些函数无法正确检测可变性 只要您不关心struct
类型需要对isimmtype(::Type{TheStructType})
进行显式定义,这就可以:
isimmtype(x::Type) = throw(ErrorException("isimmtype($x) is not defined"))
function isimmtype(::Type{T}) where {T}
if !T.isconcretetype
throw(DomainError("Abstract types are neither immutable nor mutable"))
else
return !T.mutable
end
end
isimmtype(::Type{Symbol}) = true
isimmtype(::Type{String}) = true
function isimmtype(x::Union)
return all(isimmtype, Base.uniontypes(x))
end
isimmtype(x::UnionAll) = isimmtype(x{x.var.ub})
只要您不关心struct
类型将需要对isimmtype(::Type{TheStructType})
进行显式定义,这就可以:
isimmtype(x::Type) = throw(ErrorException("isimmtype($x) is not defined"))
function isimmtype(::Type{T}) where {T}
if !T.isconcretetype
throw(DomainError("Abstract types are neither immutable nor mutable"))
else
return !T.mutable
end
end
isimmtype(::Type{Symbol}) = true
isimmtype(::Type{String}) = true
function isimmtype(x::Union)
return all(isimmtype, Base.uniontypes(x))
end
isimmtype(x::UnionAll) = isimmtype(x{x.var.ub})
你可能对……感兴趣你可能对……感兴趣