大括号内部或外部的"where"关键字之间的差异



之间有什么区别

function foo(a::Adjoint{Float64, Matrix{T}} where T)
return 0
end

function foo(a::Adjoint{Float64, Matrix{T} where T})
return 1
end

(注意大括号的位置。(

julia> methods(foo)
# 2 methods for generic function "foo":
[1] foo(a::Adjoint{Float64,Array{T,2}} where T) in Main at REPL[247]:2
[2] foo(a::Adjoint{Float64,Array{T,2} where T}) in Main at REPL[248]:2

似乎在这两种情况下,函数都会接受类型为T的矩阵的伴随?我搞不清这两种功能之间的区别

第一种是唯一类型,第二种是具体类型:

julia> isconcretetype(Adjoint{Float64, Matrix{T} where T})
true
julia> isconcretetype(Adjoint{Float64, Matrix{T}} where T)
false
julia> (Adjoint{Float64, Matrix{T}} where T) isa Core.UnionAll
true

第一个是包裹某种类型的Matrix的无穷多个邻接集。换句话说,我们可以想象用类似于的东西来表示伪代码中的无限集

Set([Adjoint{Float64, T} for T in all_possible_types])

而第二个是包裹某种类型的Matrix的伴随,或者换句话说:

Adjoint{Float64, Matrix_of_any_type}

你几乎总是想要前者,而不是后者。几乎没有理由构造一个可以包含任何Matrix的伴随,通常你只需要一个类型的伴随。

Vector:的差异更为明显

  • Vector{Vector{T}} where T是表示所有相同类型向量的唯一向量
  • CCD_ 9是包含特定元素类型CCD_

以下是一个示例,说明了Vector{Vector{T} where T}Vector{Vector{T}} where T的简单情况下的差异。

首先制作一些类型别名:

julia> const InsideWhere = Vector{Vector{T} where T}
Array{Array{T,1} where T,1}
julia> const OutsideWhere = Vector{Vector{T}} where T
Array{Array{T,1},1} where T

如果可能的话,默认的数组构造函数会将元素提升为通用类型:

julia> x = [[1, 2], [1.2, 3.4]]
2-element Array{Array{Float64,1},1}:
[1.0, 2.0]
[1.2, 3.4]
julia> x isa InsideWhere
false
julia> x isa OutsideWhere
true

但通过使用类型化的数组文字,我们可以避免自动升级:

julia> y = ( Vector{T} where T )[[1, 2], [1.2, 3.4]]
2-element Array{Array{T,1} where T,1}:
[1, 2]
[1.2, 3.4]
julia> y isa InsideWhere
true
julia> y isa OutsideWhere
false

最新更新