Julia in 函数中的抽象类型数组 [英] Arrays of abstract type in julia in functions
问题描述
我尝试理解在 Julia 中的输入,但遇到了 Array
的以下问题.我写了一个函数 bloch_vector_2d(Array{Complex,2})
;详细的实现是无关紧要的.打电话时,投诉如下:
I try to understand typing in Julia and encounter the following problem with Array
. I wrote a function bloch_vector_2d(Array{Complex,2})
; the detailed implementation is irrelevant. When calling, here is the complaint:
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
问题是父类型数组不会自动成为子类型数组的父项.
The problem is that an array of parent type is not automatically a parent of an array of child type.
julia> Complex{Float64} <: Complex
true
julia> Array{Complex{Float64},2} <: Array{Complex,2}
false
我认为在 julia 中强加 Array{Complex{Float64},2} <: Array{Complex,2}
是有意义的.或者在 Julia 中实现这一点的正确方法是什么?任何帮助或意见表示赞赏!
I think it would make sense to impose in julia that Array{Complex{Float64},2} <: Array{Complex,2}
. Or what is the right way to implement this in Julia? Any helps or comments are appreciated!
推荐答案
这个问题在 Julia 手册中有详细讨论 这里.
This issue is discussed in detail in the Julia Manual here.
引用它的相关部分:
换句话说,用类型论的说法,Julia 的类型参数是不变的,而不是协变的(甚至是逆变的).这是出于实际原因:虽然 Point{Float64}
的任何实例在概念上也可能类似于 Point{Real}
的实例,但这两种类型在内存中具有不同的表示形式:
In other words, in the parlance of type theory, Julia's type parameters are invariant, rather than being covariant (or even contravariant). This is for practical reasons: while any instance of
Point{Float64}
may conceptually be like an instance ofPoint{Real}
as well, the two types have different representations in memory:
Point{Float64}
的实例可以简洁高效地表示为一对立即数的 64 位值;Point{Real}
的一个实例必须能够容纳Real
的任何一对实例.由于 Real 实例的对象可以具有任意大小和结构,因此在实践中Point{Real}
的实例必须表示为一对指向单独分配的 Real 对象的指针.
- An instance of
Point{Float64}
can be represented compactly and efficiently as an immediate pair of 64-bit values; - An instance of
Point{Real}
must be able to hold any pair of instances ofReal
. Since objects that are instances of Real can be of arbitrary size and structure, in practice an instance ofPoint{Real}
must be represented as a pair of pointers to individually allocated Real objects.
现在回到你的问题如何编写方法签名然后你有:
Now going back to your question how to write a method signature then you have:
julia> Array{Complex{Float64},2} <: Array{<:Complex,2}
true
注意区别:
Array{<:Complex,2}
表示所有类型的联合,这些类型是 2D 数组,其 eltype 是Complex
的子类型(即,没有数组会有这个确切的类型).Array{Complex,2}
是数组可以具有的一种类型,这种类型意味着您可以在其中存储可以具有混合参数的Complex
值.
Array{<:Complex,2}
represents a union of all types that are 2D arrays whose eltype is a subtype ofComplex
(i.e. no array will have this exact type).Array{Complex,2}
is a type that an array can have and this type means that you can storeComplex
values in it that can have mixed parameter.
这是一个例子:
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
).
Also note that the notation Array{<:Complex,2}
is the same as writing Array{T,2} where T<:Complex
(or more compactly Matrix{T} where T<:Complex
).
这篇关于Julia in 函数中的抽象类型数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!