在 Julia 中检查复杂类型时规格不足

Underspecification when checking complex types in Julia

给定一些复杂的对象,例如:

> d = Dict(("a", "b")=>3, ("c", "d")=>2)
Dict{Tuple{String,String},Int64} with 2 entries:
  ("c","d") => 2
  ("a","b") => 3

我可以检查类型:

> isa(d, Dict{Tuple{String, String},Int64})
true

但是当我未指定元组类型时,检查失败:

> isa(d, Dict{Tuple,Int64})
false

是否可以在 Julia 中检查未指定的类型?如果是这样,如何?如果不是,为什么?

在 Julia 中,字典和数组一样是不变的。例如,请参阅 this question 了解适用于数组的概念。

这意味着:

julia> Int <: Number
true

但是,

julia> Vector{Int} <: Vector{Number}
false

同样,

julia> Dict{Int, String} <: Dict{Number, String}
false

但是,请注意 Dict 本身是抽象的,所以

julia> Dict{Int, String} <: Dict
true

在您提供的代码中,

julia> isa(d, Dict)
true

据我所知,如果您想具体推理字典中的这对类型,则需要明确引用它们。您可以使用 keytype(d)valtype(d) 来执行此操作。例如,根据您的问题,请注意

julia> keytype(d) <: Tuple
true

当然,如果你的字典传给了一个函数,那么你可以在函数签名中使用Dict{T1, T2},然后推理T1T2...

编辑:查看@FengyangWang 的回答,了解 v0.6 中引入的简洁的小语法快捷方式

在 Julia 0.6 中你可以简单地做

isa(d, Dict{<:Tuple, Int64})

表示 Dict 键类型是 Tuple 的子类型,值类型是 Int64.

请注意 Dict{Tuple, Int64} 不是 一个 "underspecified" 类型:它是一个具体类型并且可以有实例。但是,Dict{Tuple{String, String}, Int64} 不是一回事。前者是接受所有元组作为键的类型,而后者只接受Tuple{String, String}。这是参数不变性的一个例子。