mirror of
https://github.com/RustyCab/LearnRustEasy.git
synced 2026-02-03 18:23:31 +08:00
Update chapter_3_7.md
This commit is contained in:
@@ -140,3 +140,36 @@ fn main() {
|
||||
```
|
||||
在第2行定义String类型时,并不能确定最终字符串的大小,所以字符串内容本身应该存储在堆上。结合什么String类型的本质的内容,可以得到String类型的存储如下:
|
||||

|
||||
|
||||
String类型本身是三个字段(指针、长度、容量),在编译时是已知的大小,存储在栈上;String类型绑定的字符串(在上面代码中是“AB”)在编译时大小未知,是运行时在堆上分配内存,分配后的内存地址保存在String类型的指针字段中,内存大小保存在cap字段中,内存上存储的字符串长度保存在len字段中。
|
||||
|
||||
#### 4. move语义
|
||||
Rust所有权规则第二条,在任意时刻,值有且仅有一个所有者。那么当一个变量赋给另外一个变量时发生了什么?
|
||||
|
||||
- 完全存储在栈上的类型
|
||||
|
||||
考虑如下代码:
|
||||
```Rust
|
||||
fn main() {
|
||||
let x = 5u32;
|
||||
let y = x;
|
||||
println!("x: {:?}, y: {:?}", x, y);
|
||||
}
|
||||
```
|
||||
x和y都是u32类型,在编译时知道大小,都存储在栈上。代码第2行是将5绑定到变量x上,第3行则是通过自动拷贝的方式将5绑定到y上(先拷贝x的值5,然后将拷贝后得到的5绑定到y上)。所以,当let y = x发生后,这段代码里面最后有两个值5,分别绑定到了x和y上。
|
||||
|
||||
- 涉及到堆存储的类型
|
||||
|
||||
再考虑如下代码:
|
||||
```Rust
|
||||
fn main() {
|
||||
let s = "Hello world!".to_string();
|
||||
let s1 = s;
|
||||
// println!("s: {:?}", s); // 此行打开编译将报错
|
||||
println!("s1: {:?}", s1);
|
||||
}
|
||||
```
|
||||
s是String类型,字符串“Hello world!”是存储在堆内存上的,其内存布局如下:
|
||||

|
||||
当执行let s1 = s后,内存布局如下:
|
||||

|
||||
|
||||
Reference in New Issue
Block a user