定义
Rc
(Reference Counted)智能指针是 Rust 标准库中的一个引用计数类型,它允许多个所有者共享同一个值
相关概念:
- 共享所有权:多个
Rc
指针可以同时指向同一个数据,通过克隆来创建新的共享所有者 - 引用计数:每当
Rc
指针进行克隆时,引用计数增加;当一个Rc
指针 超出作用域时,引用计数减少。只有当引用计数为零时,数据才会被真正销毁 - 不可变:
Rc
本身是不可变的,即通过Rc
不能直接修改其内部的数据。如果需要可变共享数据,可以结合RefCell
使用 - 只适用于单线程:
Rc
的引用计数不是线程安全的,因此它只适用于单线程场景。如果你需要在多线程环境中使用,可以使用Arc
(Atomic Reference Counted)类型,它的引用计数是线程安全的
引言
我们需要实现一个如上结构的链表:
enum List{
Next(i32,Box<List>),
Nil
}
fn main() {
use List::{Next,Nil};
let a = Next(5, Box::new(Next(10,Box::new(Nil))));
let b = Next(3, Box::new(a));
let c = Next(4, Box::new(a));
}
第10行代码编译报错:value used here after move
a的值所有权已经给了b,则c不能再使用了,当这种多个变量需要共享同一个变量所有权的情况下就需要用到Rc智能指针
error[E0382]: use of moved value: `a`
--> src/main.rs:118:30
|
116 | let a = Next(5, Box::new(Next(10,Box::new(Nil))));
| - move occurs because `a` has type `List`, which does not implement the `Copy` trait
117 | let b = Next(3, Box::new(a));
| - value moved here
118 | let c = Next(4, Box::new(a));
| ^ value used here after move
Rc共享所有权
use std::rc::Rc;
enum List{
Next(i32,Rc<List>),
Nil
}
fn main() {
use List::{Next,Nil};
let a = Rc::new(Next(5, Rc::new(Next(10,Rc::new(Nil)))));
let b = Next(3, Rc::clone(&a));
let c = Next(4, Rc::clone(&a));
println!("*********")
}
方式二
fn main() {
use List::{Next,Nil};
let a = Rc::new(Next(5, Rc::new(Next(10,Rc::new(Nil)))));
let b = Next(3, a.clone()); // 直接调用Rc变量的clone方法
let c = Next(4, a.clone());
println!("*********")
}
Rc引用计数
fn main() {
use List::{Next, Nil};
let a = Rc::new(Next(5, Rc::new(Next(10, Rc::new(Nil)))));
println!("count after creating a = {}", Rc::strong_count(&a));
let b = Next(3, a.clone());
println!("count after bind to b, a count = {}", Rc::strong_count(&a));
{
let c = Next(4, a.clone());
println!("count after bind to c, a count = {}", Rc::strong_count(&a));
}
println!("count end, a count = {}", Rc::strong_count(&a));
}
// 输出:
// count after creating a = 1
// count after bind to b, a count = 2
// count after bind to c, a count = 3
// count end, a count = 2