mirror of
https://github.com/alrayyes/wiki.git
synced 2024-11-22 11:36:23 +00:00
63 lines
1.6 KiB
Markdown
63 lines
1.6 KiB
Markdown
|
---
|
|||
|
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
|
|||
|
shouldn’t be cleaned up unless it doesn’t 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));
|
|||
|
}
|
|||
|
```
|