《Rust 编程第一课》 学习笔记 Day 20

101 阅读2分钟

大家好,我是砸锅。一个摸鱼八年的后端开发。熟悉 Go、Lua。第二十天还是继续和大家一起学习 Rust😊

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情

内存管理

struct

Rust 在内存中排布数据时,会根据每个域的对齐(aligment) 对数据进行重排,使其内存大小和访问效率最好。因为 CPU 在加载不对齐的内存时,性能会急剧下降

虽然 Rust 编译器会默认帮开发者优化结构体的排列,但是可以使用 #[repr] 宏强制让 Rust 编译器不做优化,达到和 C 一样的行为

enum

在 Rust 下,enum 是标签联合体,它的大小是标签的大小,加上最大类型的长度

Option 是 有值 / 无值 的简单枚举类型,它的 tag 只有两种情况:0 或者 1,tag 为 0 时,表示 None,tag 为 1 时,表示 Some

Result<T, E> 是成功返回的数据 / 错误返回的数据 的枚举类型

image.png

Vec 和 String

String 和 Vec 是占用相同大小的,都是 24 个字节,String 底层结构内部就是一个 Vec

Vec 是三个 word 的胖指针,里面包含一个指向堆内存的指针 pointer、分配的堆内存的容量 capacity、数据在堆内存的长度 length

image.png

值的销毁

当所有者离开作用域,它拥有的值就会被丢弃。这是通过 Drop trait 实现的,一个值要被释放的时候,这个值的 drop() 函数就会被自动调用,类似面向对象编程里的析构函数

如果释放的是一个复杂的数据结构,那么这个结构体在调用 drop() 时,就会依次调用每个域的 drop 函数,一直递归执行下去,直到每个域都释放干净

释放其他资源

Drop trait 除了释放内存,还可以释放任何资源,例如 socket、文件、锁等

例如创建一个文件:

    
use std::fs::File;
use std::io::prelude::*;

fn main() -> std::io::Result<()> {
    let mut file = File::create("foo.txt)?;
    file.write_all(b"hello world")?;
    Ok(())
}   
    

当 file 离开作用域时,它的内存会被释放,它占用的资源、操作系统打开的文件描述符也会被释放

如何区分深拷贝与浅拷贝:当b复制了a以后,修改a,观察b是否会发生变化

深拷贝:修改a以后,b不会发生变化

浅拷贝:修改a以后,b也会跟着变化