wiki/content/20200929145534-rc_t.md

64 lines
1.6 KiB
Markdown
Raw Normal View History

2024-05-06 20:40:05 +00:00
---
2024-10-30 17:34:11 +00:00
date: 2020-09-29
2024-05-06 20:40:05 +00:00
id: 13459bc1-66f2-4eed-b987-061bd0fbeb1c
title: Rc\<T\>
---
# Introduction
In the majority of cases, ownership is clear: you know exactly which
variable owns a given value. However, there are cases when a single
value might have multiple owners. For example, in graph data structures,
multiple edges might point to the same node, and that node is
conceptually owned by all of the edges that point to it. A node
shouldnt be cleaned up unless it doesnt have any edges pointing to it.
To enable multiple ownership, Rust has a type called `Rc<T>`, which is
an abbreviation for reference counting. The `Rc<T>` type keeps track of
the number of references to a value which determines whether or not a
value is still in use. If there are zero references to a value, the
value can be cleaned up without any references becoming invalid.
# Reason to choose Rc\<T\>
`Rc<T>` enables multiple owners of the same data;
[Box\<T\>](20200929135609-box_t) and
[RefCell\<T\>](20200929152628-refcell_t) have single owners.
# Example
This won't compile because b & c both share ownership of a:
``` rust
enum List {
Cons(i32, Box<List>),
Nil,
}
use crate::List::{Cons, Nil};
fn main() {
let a = Cons(5, Box::new(Cons(10, Box::new(Nil))));
let _b = Cons(3, Box::new(a));
let _c = Cons(4, Box::new(a));
}
```
The solution:
``` rust
enum List {
Cons(i32, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
use std::rc::Rc;
fn main() {
let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
let _b = Cons(3, Rc::clone(&a));
let _c = Cons(4, Rc::clone(&a));
}
```