我尝试理解在Julia中键入文字,并遇到以下问题Array
。我写了一个函数bloch_vector_2d(Array{Complex,2})
; 详细的实现是无关紧要的。打电话时,有以下投诉:
julia> bloch_vector_2d(rhoA)
ERROR: MethodError: no method matching bloch_vector_2d(::Array{Complex{Float64},2})
Closest candidates are:
bloch_vector_2d(::Array{Complex,2}) at REPL[56]:2
bloch_vector_2d(::StateAB) at REPL[54]:1
Stacktrace:
[1] top-level scope at REPL[64]:1
问题在于父类型数组不能自动成为子类型数组的父对象。
julia> Complex{Float64} <: Complex
true
julia> Array{Complex{Float64},2} <: Array{Complex,2}
false
我认为在茱莉亚实行这一点是有道理的Array{Complex{Float64},2} <: Array{Complex,2}
。还是在Julia中实施此方法的正确方法是什么?任何帮助或评论表示赞赏!
此处在Julia手册中详细讨论了此问题。
引用其中的相关部分:
换句话说,用类型论的话来说,Julia的类型参数是不变的,而不是协变的(甚至是协变的)。这是出于实际的原因:尽管任何实例在
Point{Float64}
概念上也可能像实例Point{Real}
,但两种类型在内存中具有不同的表示形式:
- 的一个实例
Point{Float64}
可以紧凑而有效地表示为64位值的直接对。- 的一个实例
Point{Real}
必须能够容纳的任意一对实例Real
。由于作为Real实例的对象可以具有任意大小和结构,因此在实践中,Point{Real}
必须将的实例表示为指向单独分配的Real对象的一对指针。
现在回到您的问题,如何编写方法签名,那么您将:
julia> Array{Complex{Float64},2} <: Array{<:Complex,2}
true
注意区别:
Array{<:Complex,2}
表示2D数组的所有类型的并集,其eltype是的子类型Complex
(即,没有数组将具有此确切类型)。Array{Complex,2}
是数组可以具有的类型,并且该类型意味着您可以Complex
在其中存储可以具有混合参数的值。这是一个例子:
julia> x = Complex[im 1im;
1.0im Float16(1)im]
2×2 Array{Complex,2}:
im 0+1im
0.0+1.0im 0.0+1.0im
julia> typeof.(x)
2×2 Array{DataType,2}:
Complex{Bool} Complex{Int64}
Complex{Float64} Complex{Float16}
另请注意,该符号Array{<:Complex,2}
与书写相同Array{T,2} where T<:Complex
(或更紧凑Matrix{T} where T<:Complex
)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句