【问题标题】:Question about Julia type syntax: Why is Array{Int32, 1} <: Array{Integer, 1} false?关于 Julia 类型语法的问题:为什么 Array{Int32, 1} <: Array{Integer, 1} 为假?
【发布时间】:2020-02-25 00:16:23
【问题描述】:

在朱莉娅中,

Array{Int32, 1} <: Array{Integer, 1} 

计算为false,但是

Array{Int32, 1} <: (Array{T, 1} where T <: Integer)

计算为true,因为Int32 &lt;: Integer 为真。

在我看来,第一个和第二个表达式传达了相同的想法,并且应该等效地评估。此外,第一个表达式不太混乱。为什么 Julia 的语法将前者评估为假,而将后者评估为真,有什么原因吗?这种行为是否有一些深刻而好的方面,或者这是对数组/类型系统开发方式的疏忽?

【问题讨论】:

    标签: julia


    【解决方案1】:

    参见手册中的Parametric Composite Types

    具有不同T 值的具体Point 类型绝不是彼此的子类型:

    julia> Point{Float64} <: Point{Int64}
    false
    
    julia> Point{Float64} <: Point{Real}
    false
    

    警告 最后一点非常重要:即使Float64 &lt;: Real 我们拥有Point{Float64} &lt;: Point{Real}

    换句话说,用类型论的说法,Julia 的类型参数是不变的,而不是covariant (or even contravariant)

    这是出于实际原因:虽然Point{Float64} 的任何实例在概念上也可能类似于Point{Real} 的实例,但这两种类型在内存中的表示方式不同:

    • Point{Float64} 的实例可以简洁有效地表示为一对 64 位的立即数;

    • Point{Real} 的实例必须能够容纳Real 的任何一对实例。由于Real 实例的对象可以是任意大小和结构,实际上Point{Real} 实例必须表示为一对指向单独分配的Real 对象的指针。

    【讨论】:

      【解决方案2】:

      Array{Integer, 1}Array{T, 1} where T &lt;: Integer 的主要区别在于前者是具体类型,而后者是抽象类型。之所以会有所不同,是因为您可以创建一个类型为Array{Integer, 1} 的变量。这是一个潜在的异构数组,因此必须将其实现为指针数组(如此缓慢且堆分配)。考虑到这一点,Array{Int32, 1} &lt;: Array{Integer, 1}=false 的原因就很清楚了。如果我们为特定类型 Array{Integer, 1} 编写一个方法,因为它已经是一个具体类型,所以不能专门化,并且当我们在具有完全不同的数据格式(内联元素)的 Array{Int32, 1} 上运行它时会出现段错误)。

      【讨论】:

      • 有道理!谢谢。
      【解决方案3】:

      discussions 关于将您描述的行为设为默认行为,但他们最终达成共识,认为当前可能会更好。

      基本上,它是Vector{Integer} 含义的语法选择。有三种类型的差异可供选择:

      julia> Vector{Int32} <: (Vector{T} where T <: Integer)
      true
      
      julia> Vector{Any} <: (Vector{T} where T >: Integer)
      true
      
      julia> Vector{Integer} <: (Vector{T} where {T >: Integer, T <: Integer})
      true
      

      这三种方差对应于对变量的三种不同操作。读的协变、写的逆变和两者的不变性。例如,在 Rust 中,&amp;'a TT 是协变的,因为您只能从中读取,而 &amp;'a mut T 是不变的,因为它既可以读取也可以写入。如果有“只写”类型,逆变将是一个理智的默认值。鉴于 Julia 中的变量既可读又可写,默认为不变性看起来是一个不错的选择。

      【讨论】:

        猜你喜欢
        • 2019-11-06
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        • 1970-01-01
        • 2011-12-01
        • 2011-08-15
        • 1970-01-01
        • 2015-01-16
        相关资源
        最近更新 更多