Julia 如何知道某个对象的类型是什么?对 `Vector{Int64}` 的引用的内存布局是什么?

问题描述 投票:0回答:1

我正在尝试了解有关 Julia 类型系统如何工作的更多细节。

考虑以下简单示例

julia> v = [1]
1-element Vector{Int64}:
 1

julia> typeof(v)
Vector{Int64} (alias for Array{Int64, 1})

julia> vany::Vector{Any} = v
1-element Vector{Int64}:
 1

julia> typeof(vany)
Vector{Any} (alias for Array{Any, 1})

我很想知道发生了什么(如果有的话)使

vany
v
不同?

这似乎是一个简单的问题,但我相信它实际上是相当微妙的。

让我们考虑几点:

  • 最初,初始化时没有提供类型信息
    v
    。我认为我的猜测是正确的,Julia 已经检查了该表达式右侧的对象,并得出结论,它分配给
    v
    的类型是包含所有整数元素的
    Vector
    。默认情况下,使用
    Int64
    类型表示整数。因此 Julia 得出结论,
    v
    必须引用
    Vector{Int64}
  • 但是,我不清楚这到底是什么意思。我认为 v 一定是某个分配的对象,它引用向量元素所在的内存块。我不确定这个v
    是否存在于堆的堆栈上。它引用的
    data
    是动态长度向量,必须存在于堆上。我还认为 Julia 必须在引用中添加一些类型信息。这样它就知道 
    v 引用了 Vector{Int64}
    。但我对此并不完全确定。
    将这个问题改写为 
  • 对象的内存布局是什么
v

 可能是合理的
考虑以下代码行时,事情会变得更加复杂。

vany::Vector{Any} = v

这里到底发生了什么?

v
    的元素是否单独从
  • Int64
    转换为
    Any
    这是否意味着向量的每个元素现在都是一个具有额外间接级别的对象? (这意味着每个元素都是一个 
    Any
  • ,它是一个“盒装”对象。)
  • Julia 如何知道 
    vany
  • 引用了
  • Vector{Any}
     而不是 
    Vector{Int64}
    ?该类型信息保存在哪里?
    
    
  • 我也许应该添加以下信息:

julia> typeof(v[1]) Int64 julia> typeof(vany[1]) Int64

看起来两个向量的元素仍然是
Int64

我不确定这是否意味着:

要么:两个向量在内存中的表示是相同的,这意味着转换为

::Vector{Any}
    实际上并没有做任何事情,除了复制向量并在
  • vany
     上设置一些元数据,以便它认为它是 
    ::Vector{Any}
     而不是 
    Vector{Int64}
    
    
    或: 
    vany
  • 的所有元素现在都装箱在
  • Any
     内,但是函数调用 
    typeof
     遵循装箱内容以找出在本例中它包含 
    Int64
     
        
这里引起混乱的一个大问题是 Julia 是一种动态类型语言。因此,变量没有类型,而值有。变量只是值的临时名称。因此,读取
julia type-inference type-systems memory-model
1个回答
0
投票
的正确方法是

[1]

Vector
 的构造函数,其参数都是 
Int64
。因此,
[1]
 会产生 
Vector{Int64}
Julia 中对象的内存表示有些复杂(因为实现高性能需要很大的自由度),但 TLDR 是 
Vector{Int}

是一个装箱对象,这意味着它分配有类型标签。类型标签有 2 个字,告诉运行时变量的类型是什么以及保存一些用于 GC 的元数据。类型有一个布局,而

Vector{Int}

 的布局意味着 
Int
 是内联存储的(从技术上讲,因为 
Vector
 是可调整大小的,所以还有另一个重定向,并且 
Vector
 拥有固定大小的 
Memory
,但那是一个很多细节在这里并不重要)。
v 的元素是否单独从 Int64 转换为 Any?

不。

Any
是一个抽象类型。值不能具有类型

Any

。这里发生的是构造一个新的 
Vector{Any}
 并将 
v
 中的元素复制到 
vany
Julia 如何知道 vany 引用的是 Vector{Any} 而不是 Vector{Int64}?该类型信息保存在哪里?

类型标签

这是否意味着向量的每个元素现在都是一个具有额外间接级别的对象?

是的。

Vector{Any}
的布局是一个盒子数组。

	

© www.soinside.com 2019 - 2024. All rights reserved.