Rc<T> 引用计数

大部分情况下, 变量的所有权是可以确定的. 然而有时候单个值可能有多个所有者.

如在图数据结构中, 多个边可以链接同一个节点, 这个节点为所有边持有, 在这些边被销毁之前, 这个节点都应该保留.

Rust中使用 Rc<T>来实现多所有权, 它是 引用计数 (Reference Count) 的缩写.

引用计数通过记录一个值的引用数量来知晓这个值是否仍然在使用, 如果没有引用这意味着这个值应该被销毁.

Rc<T> 用于当希望在堆上分配一些内存供程序的多个部分读取, 而且无法在编译时确定程序的哪一部分会最后结束使用时.

如果确实知道哪部分是最后使用的时候, 直接令其成为数据的所有者, 正常的所有权规则就可以在编译时生效

PS: Rc<T> 只能用于单线程

使用 Rc<T> 共享数据

Try in Playground

Rust展开
12345678910111213141516171819
use std::rc::{Rc};

#[derive(Debug)]
enum Node {
    Next(Rc<Node>),
    None
}

fn main(){
  let a = Node::None;
  let n = Rc::new(a);
  
  let b = Node::Next(Rc::clone(&n));
  let c = Node::Next(n.clone());
  println!("b = {:?}, c = {:?}", b, c);
}

// output:
// b = Next(None), c = Next(None)

n.clone Rc::clone(&n)是一样的

Rc::clone 只会增加引用计数, 而不是深拷贝, 因此这个代价是很小的

可以通过 Rc::strong_count(&n)来获取当前引用的数量.

通过不可变引用, Rc<T> 可以在程序的多个部分共享只读数据, 如果 Rc<T> 允许多个可变引用,则会违反借用规则:

相同的作用域内多个可变借用可能造成数据竞争(data race)和不一致.

- roadup -