为什么在 Julia 中有许多不同的抽象类型调度方式?它们之间有什么区别?

Moh*_*mal 4 julia

在 julia 中声明具有抽象类型的函数的这三种不同方式之间的本质区别是什么?

Base.zero(::AbstractZero) = Zero()
Run Code Online (Sandbox Code Playgroud)
Base.zero(::Type{<:AbstractZero}) = Zero()
Run Code Online (Sandbox Code Playgroud)
Base.zero(::Type{T}) where T <: AbstractZero = Zero()
Run Code Online (Sandbox Code Playgroud)

Bog*_*ski 5

Base.zero(::Type{<:AbstractZero}) = Zero()
Run Code Online (Sandbox Code Playgroud)

Base.zero(::Type{T}) where T <: AbstractZero = Zero()
Run Code Online (Sandbox Code Playgroud)

几乎相同。在这种情况下,它们是相同的。

不同之处在于,如果您想T在某个函数的定义中使用(如在第一种情况下它是未定义的)。

准确地说:

Base.zero(::Type{<:AbstractZero}) = Zero()
Run Code Online (Sandbox Code Playgroud)

扩展为:

zero(::Type{var"#s1"} where var"#s1"<:AbstractZero)
Run Code Online (Sandbox Code Playgroud)

但范围的差异可以忽略不计。


现在之间的区别:

Base.zero(::AbstractZero) = Zero()
Run Code Online (Sandbox Code Playgroud)

Base.zero(::Type{<:AbstractZero}) = Zero()
Run Code Online (Sandbox Code Playgroud)

是第一个调度给定类型的对象,第二个调度一个类型本身。这是一个 MWE:

julia> f(::Integer) = "integer passed"
f (generic function with 1 method)

julia> f(::Type{<:Integer}) = "integer type passed"
f (generic function with 2 methods)

julia> f(1)
"integer passed"

julia> f(Int)
"integer type passed"
Run Code Online (Sandbox Code Playgroud)