Rust 当函数的堆栈中有一个对变量的引用作为其参数时,到底分配给它的是什么?
我们了解了函数如何将其参数数据保存在堆栈中。这可能是基元类型的值,也可能是指向堆上数据的指针。现在,当参数是对某物的引用时,它在堆栈中是如何表示的呢?在内部,引用,即Rust 当函数的堆栈中有一个对变量的引用作为其参数时,到底分配给它的是什么?,rust,Rust,我们了解了函数如何将其参数数据保存在堆栈中。这可能是基元类型的值,也可能是指向堆上数据的指针。现在,当参数是对某物的引用时,它在堆栈中是如何表示的呢?在内部,引用,即&'T基本上只是一个指针。不同之处在于,Rust的静态编译规则保证了内存安全。就像你刚才在那一章读到的规则一样。当您将参数传递给时,比如一个具有如下签名的函数: struct-UnitBar(i32); fn foo(数据:&UnitBar); 你这样称呼它: struct-UnitBar(i32); fn main(){ 设ba
&'T
基本上只是一个指针。不同之处在于,Rust
的静态编译规则保证了内存安全。就像你刚才在那一章读到的规则一样。当您将参数传递给时,比如一个具有如下签名的函数:
struct-UnitBar(i32);
fn foo(数据:&UnitBar);
你这样称呼它:
struct-UnitBar(i32);
fn main(){
设bar=UnitBar(0);//Sizeof bar是Sizeof i32
foo&bar;
}
Rust将分配一个UnitBar
,在本例中为4字节。然后,它将分配一个指向条
的指针,该指针的大小与计算机中的本机指针相同,或者更习惯地说与rust中的usize相同。请注意,在内存级别上,指针和引用之间没有区别。在静态编译级别,或者在代码中,存在静态编译时检查,以确保代码遵循rust的规则。从这里开始,fn foo
中的data
参数将表示为内存中的指针。此不会在每次传递到另一个函数或作用域时复制它所指向的数据
虽然不能保证看起来像这样,因为编译器可以在内存中移动东西以生成更高效的程序,但这就是它的工作原理
作为旁注,有3种特殊情况:
&[T]
是一种特殊类型,其中包含*const T
和usize
。它是这个的c等价物:&str
。这本质上是一个&[u8]
,因此它也遵循上面的内存模型,但可以确保它包含的所有字符(即其中存储的字节配置)都是UTF-8&dyn std::fmt::Debug
。对于c/c++程序员来说,它的大小也是两个usize
s或两个size\t
s。第一个指针指向数据,第二个指针指向vtable,其中存储了每个函数的函数签名&T
基本相同:
Option<&T> -|
Box<T> |
Rc<T> - These all have the same size as `&T`
Arc<Mutex<T>> |
struct Foo(&T) -|
选项-|
盒子|
Rc-这些都与`&T的大小相同`
弧|
结构Foo&T-|
作为编辑,是这些指针大小相同的证明。您确定智能指针(
Rc
,Arc
,等等)的大小与&T
相同吗?除了封装的数据,它们都有额外的状态。@apemanzilla是的,一开始我会相信,但奇怪的是,它们的大小是一样的。请看我发布的编辑。@apemanzillaRc
和Arc
将refcount存储在“框”中,与T
对齐。它们没有独立的数据指针和ReCube指针,就像C++中的代码> SyddYPPT/<代码>中所看到的。注意:你的3个特殊情况通常被称为动态大小的类型。无法保证DST的布局,过去有人建议将和(Add+Sub)
表示为两个v-ptr+一个数据ptr。
Option<&T> -|
Box<T> |
Rc<T> - These all have the same size as `&T`
Arc<Mutex<T>> |
struct Foo(&T) -|