函数中julia中的抽象类型数组 [英] Arrays of abstract type in julia in functions

查看:68
本文介绍了函数中julia中的抽象类型数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试理解在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!

推荐答案

此问题在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 of Point{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 of Real. Since objects that are instances of Real can be of arbitrary size and structure, in practice an instance of Point{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 of Complex (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 store Complex 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆