函数中julia中的抽象类型数组 [英] 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
我认为在朱莉娅中强加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!
推荐答案
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中的抽象类型数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!