从 Rust 基础到掌握 — 第 8 集
通过 Box、Rc、Arc 选择您的所有权结构
该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。
大多数值只能由局部变量和集合拥有。 当您需要坚持堆或在多个所有者之间共享时,请选择适合您目的的智能指针。
Box
enum Node {
Value(i32, Box<Node>),
End,
}
let list = Node::Value(
10,
Box::new(Node::Value(20, Box::new(Node::End))),
);
对于递归类型,在编译时无法立即知道下一个值的大小。 Box 将值放置在堆上,并以当前类型存储固定大小的指针。
Box 不会自动共享,并且仍然只有一个主要所有者。
RC 和 Arc
use std::rc::Rc;
let data = Rc::new(String::from("ItemTable"));
let ui_data = Rc::clone(&data);
let game_data = Rc::clone(&data);
rc 允许多个地方在单个线程中拥有相同的值。 当最后一个Rc消失时,这些值被清除。
跨多个线程共享需要 Arc,它使用原子引用计数。 Rc和Arc默认情况下不使其内部值可变。
内部变异性
use std::cell::RefCell;
use std::rc::Rc;
let score = Rc::new(RefCell::new(0));
*score.borrow_mut() += 10;
RefCell 在运行时而不是编译时检查借用规则。 同时,如果借用不正确,程序会发生恐慌,因此编译检查不会消失。
通常使用 Arc 和 Mutex 的组合在线程之间同步更改访问。
如果重叠很多智能指针,就很难理解所有权结构。 首先要检查Box拥有堆、Rc与单线程共享、Arc在线程间共享的目的,并选择最简单的类型。