Collections Vec,整数向量vs字符串向量,为什么即使元素在堆上,我也可以索引/复制int元素?

Collections Vec,整数向量vs字符串向量,为什么即使元素在堆上,我也可以索引/复制int元素?,collections,rust,heap,Collections,Rust,Heap,简单地说,有些数据类型存储在堆栈上,因为编译器知道它们在运行时需要多少内存。其他数据类型更灵活,存储在堆中。数据指针保持在堆栈上,指向堆数据 我的问题是,如果Vec数据在堆上,那么i32和其他通常堆栈存储的类型如何能够像实际在通过索引复制的堆栈上一样被访问 换句话说。这对我来说很有意义,我不能从Vec中移出字符串,它们不实现复制,通常是移动的。当它们是Vec的元素时,也会发生同样的情况。然而,i32通常是被复制的,但是当它们是堆上向量数据的一部分时,为什么也会发生这种情况呢 请随时指出任何概念上

简单地说,有些数据类型存储在堆栈上,因为编译器知道它们在运行时需要多少内存。其他数据类型更灵活,存储在堆中。数据指针保持在堆栈上,指向堆数据

我的问题是,如果Vec数据在堆上,那么i32和其他通常堆栈存储的类型如何能够像实际在通过索引复制的堆栈上一样被访问

换句话说。这对我来说很有意义,我不能从Vec中移出字符串,它们不实现复制,通常是移动的。当它们是Vec的元素时,也会发生同样的情况。然而,i32通常是被复制的,但是当它们是堆上向量数据的一部分时,为什么也会发生这种情况呢

请随时指出任何概念上的错误,并指出我现有的材料,如果你认为我错过了一些东西。我已经阅读了Rust编程语言并进行了一些检查

fn main() {
    // int in stack
    let i: i32 = 1;
    let _ic = i;
    println!("{}", i);

    // String on heap
    let s: String = String::from("ciao cippina");
    let _sc = &s;
    println!("{}", s);

    // array and data on the stack
    let ari = [1, 2, 3];
    println!("{:?}", &ari);
    println!("a 0 {}", ari[0]);

    // array and Pointers on the stack, data on the heap
    let ars = [String::from("ciao"), String::from("mondo")];
    println!("{:?}", &ars);
    println!("a 0 {}", ars[0]);
    // let _ars_1 = ars[0];  // ERROR, cannot move out of array

    // Vec int, its Pointer on stack, all the rest on heap
    let veci = vec![2, 4, 5, 6];
    println!("{:?}", &veci);
    println!("a 0 {}", veci[0]);
    let _veci_1 = veci[0];  // NO ERROR HERE ??

    // Vec string, its Pointer on stack, all the rest on heap
    let vecs = vec![String::from("ciao"), String::from("mondo")];
    println!("{:?}", &vecs);
    println!("a 0 {}", vecs[0]);
    // let _vecs_1 = vecs[0];  // ERROR, cannot move out of Vec
}

向量的元素存在于堆上并不意味着编译器不能知道元素的大小。元素位于何处并不重要,如果类型是可复制的,则可以从堆栈->堆复制它,反之亦然


在您的例子中,i32占用4个字节,无论是在堆上还是在堆栈上,都忽略了对齐问题

是的,动机与Vivek在这里指出的相同。我想我得到了这样一个想法:从堆中复制比较慢,所以移动是首选,不管类型是否可复制。泰克斯所有人的评论和答案。