【发布时间】:2019-10-13 15:04:18
【问题描述】:
在 Julia 中,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
这很有用,可以回答许多但不是所有类型的问题。到目前为止,我注意到的故障分为两类:
- 这种模式适用但相对于 Julia 文档给出错误答案的类型。我发现的唯一示例是 String 和 Symbol,两者都被认为是不可变的,但返回 false。那里有关于此的错误报告,所以我的下意识的解决方案是只为这些类型编写方法,显式覆盖 行为
-
此模式失败的类型。其中包括
Union和UnionAll类型。两者似乎都有简单的解决方案。对于UnionAll,我们可以使用类型变量的上限来测试类型的具体化。对于Union{A,B},我们可以比较A和B类型的可变性,推导出联合的可变性。
我继续将这些解决方案写成我认为合理的类似特征的语法,并且它部分有效:
"""
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
如果定义了除最后一个之外的所有这些方法,那么mutability 函数将按我的预期工作,但Union{A,B} 类型除外,它始终标记为未知。但是,如果定义了最后一个方法,则它匹配 Int64 之类的类型,甚至没有在函数体中绑定 B(即,在方法的开头添加 println(A, B) 会导致错误,因为 B not被定义)。我可以看到A <: Union{A,B} 中存在歧义,但是如何明确匹配关于Union 类型的查询?在这种情况下,如何防止Type{Union{A,B}} 匹配Type{A}?
另外:此mutability 函数是否存在其他错误标记的情况?
【问题讨论】:
标签: methods types julia dispatch union-types