gpt4 book ai didi

rust - 当函数引用变量作为参数时,函数的堆栈到底分配了什么?

转载 作者:行者123 更新时间:2023-11-29 08:03:36 25 4
gpt4 key购买 nike

我们读到Ownership函数如何将其参数数据保存在堆栈中。在基本类型的情况下,这可能是一个值,也可能是指向驻留在堆上的数据的指针。现在,当参数是对某物的引用时,参数在堆栈中如何表示?

最佳答案

在内部,引用,即&'a T基本上只是一个指针。不同之处在于,您拥有由 Rust 的静态编译规则保证的内存安全。就像您刚刚在该章中读到的规则一样。当您传递参数时,请说一个具有如下签名的函数:

struct UnitBar(i32);
fn foo(data: &UnitBar);

你这样调用它:

struct UnitBar(i32);
fn main() {
let bar = UnitBar(0); //Sizeof bar is sizeof i32
foo(&bar);
}

Rust 将分配一个 UnitBar 在本例中为 4 个字节。然后,它将分配一个指向 bar 的指针,该指针的大小与计算机中的 native 指针相同,或者更惯用地与 rust 中的 usize 大小相同。这里请注意,指针和引用在内存级别没有区别。在静态编译级别或在您的代码中,有静态编译时检查以确保您的代码遵循 Rust 的规则。从这里开始,fn foo 中的data 参数将表示为内存中的指针。每次将其指向的数据传递到另一个函数或作用域时,不会复制它所指向的数据。

虽然不能保证看起来像这样,但由于编译器可以在内存中移动内容以生成更高效的程序,这几乎就是它的工作原理。


顺便说一句,有 3 种特殊情况:

  1. 切片的情况。 &[T] 将需要两个“指针长度”来存储。为什么?因为&[T]是一种特殊类型,它包含一个*const T和一个usize。它在 c 语言中相当于:
struct SliceReference {
*const T data;
size_t length;
}
  • 另一个(类似的情况)是&str。这本质上是一个 &[u8],因此它也遵循上面的内存模型,但相反,它向您保证它包含的所有字符,即存储在其中的字节配置,都是 UTF- 8.
  • 这是最后一种情况,其中存在特征对象。即,&dyn std::fmt::Debug。对于 c/c++ 程序员来说,它的大小又是两个 usize 或两个 size_t。第一个指针指向数据,第二个指针指向 vtable,其中存储了每个函数的函数签名。
  • 请注意,上述所有内容都与内存中的 &T 本质上相同:

    Option<&T>     -|
    Box<T> |
    Rc<T> - These all have the same size as `&T`
    Arc<Mutex<T>> |
    struct Foo(&T) -|

    作为编辑,here证明这些尺寸都是相同的。

    关于rust - 当函数引用变量作为参数时,函数的堆栈到底分配了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55009498/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com