Julia:Type和DataType之间的差异

时间:2017-02-16 20:20:03

标签: types julia

对我来说,他们似乎是一样的。由于Type属于DataType类型,反之亦然,它们如何不等同?我应该何时使用其中一种?

> isa(DataType, Type)
true

> typeof(Type)
DataType

> isa(Type, DataType)
true

> typeof(DataType)
DataType

1 个答案:

答案 0 :(得分:7)

TypeDataType本身就是两种类型。正如您所发现的,大多数类型的类型都是DataType。在这种情况下,DataType是摘要Type

的子类型
julia> supertype(DataType)
Type{T}

julia> supertype(Type)
Any

julia> DataType <: Type
true

这意味着isa DataType也将是Type的任何内容 - Julia 中的这么多类型都是 isa。还有Type的其他子类型,包括UnionTypeConstructor s。这意味着julia中的所有类型都属于Type类型,但即使像Vector这样的简单内容也不属于DataType类型。

Type很特别。如上所示,它是参数化的。这允许您精确指定相关特定类型的类型。因此,虽然朱莉娅isa Type中的每一种类型都只有Int isa Type{Int}

julia> isa(Int, Type{Int})
true

julia> isa(Float64, Type{Int})
false

julia> isa(Float64, Type)
true

此功能对于Type来说是特殊且独特的,并且在允许在特定类型上指定调度时必不可少。例如,许多函数允许您将类型指定为第一个参数。

f(x::Type{String}) = "string method, got $x"
f(x::Type{Number}) = "number method, got $x"

julia> f(String)
"string method, got String"

julia> f(Number)
"number method, got Number"

值得注意的是Type{Number} Number的类型,而不是Int的类型,即使是Int <: Number!这是参数不变性。要允许特定抽象类型的所有子类型,可以使用函数参数:

julia> f(Int)
ERROR: MethodError: no method matching f(::Type{Int64})

julia> f{T<:Integer}(::Type{T}) = "integer method, got $T"
f (generic function with 3 methods)

julia> f(Int)
"integer method, got Int64"

将有问题的特定类型捕获为函数参数的功能非常强大且经常使用。请注意,我甚至不需要指定参数名称 - 在这种情况下唯一重要的是Type{}中的参数。

这对于什么是一个非常简短的答案来说是一个很长的解释:你通常不想使用DataType,因为它不会涵盖朱莉娅的所有类型。相反,您应该使用Type来描述任何或所有类型的类型。如果要特别描述Type{T}的类型,请使用T