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

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

问题描述

我尝试理解在 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 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 in 函数中的抽象类型数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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