Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new example for Rc. #1223

Merged
merged 1 commit into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
- [HashMap](std/hash.md)
- [Alternate/custom key types](std/hash/alt_key_types.md)
- [HashSet](std/hash/hashset.md)
- [`Rc`](std/rc.md)

- [Std misc](std_misc.md)
- [Threads](std_misc/threads.md)
Expand Down
54 changes: 54 additions & 0 deletions src/std/rc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# `Rc`

When multiple ownership is needed, `Rc`(Reference Counting) can be used. `Rc` keeps track of the number of the references which means the number of owners of the value wrapped inside an `Rc`.

Reference count of an `Rc` increases by 1 whenever an `Rc` is cloned, and decreases by 1 whenever one cloned `Rc` is dropped out of the scope. When an `Rc`'s reference count becomes zero, which means there are no owners remained, both the `Rc` and the value are all dropped.

Cloning an `Rc` never do a deep copy. Cloning creates just another pointer to the wrapped value, and increments the count.

```rust,editable
use std::rc::Rc;

fn main() {
let rc_examples = "Rc examples".to_string();
{
println!("--- rc_a is created ---");

let rc_a: Rc<String> = Rc::new(rc_examples);
println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a));

{
println!("--- rc_a is cloned to rc_b ---");

let rc_b: Rc<String> = Rc::clone(&rc_a);
println!("Reference Count of rc_b: {}", Rc::strong_count(&rc_b));
println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a));

// Two `Rc`s are equal if their inner values are equal
println!("rc_a and rc_b are equal: {}", rc_a.eq(&rc_b));

// We can use methods of a value directly
println!("Length of the value inside rc_a: {}", rc_a.len());
println!("Value of rc_b: {}", rc_b);

println!("--- rc_b is dropped out of scope ---");
}

println!("Reference Count of rc_a: {}", Rc::strong_count(&rc_a));

println!("--- rc_a is dropped out of scope ---");
}

// Error! `rc_examples` already moved into `rc_a`
// And when `rc_a` is dropped, `rc_examples` is dropped together
// println!("rc_examples: {}", rc_examples);
// TODO ^ Try uncommenting this line
}
```

### See also

[std::rc][1] and [Arc][2].

[1]: https://doc.rust-lang.org/std/rc/index.html
[2]: https://doc.rust-lang.org/std/sync/struct.Arc.html