1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-12-03 09:45:17 +02:00

Publish Comprehensive Rust 🦀

This commit is contained in:
Martin Geisler
2022-12-21 16:36:30 +01:00
commit c212a473ba
252 changed files with 8047 additions and 0 deletions

31
src/std/box-niche.md Normal file
View File

@@ -0,0 +1,31 @@
# Niche Optimization
```rust,editable
#[derive(Debug)]
enum List<T> {
Cons(T, Box<List<T>>),
Nil,
}
fn main() {
let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
println!("{list:?}");
}
```
A `Box` cannot be empty, so the pointer is always valid and non-`null`. This
allows the compiler to optimize the memory layout:
```bob
Stack Heap
.- - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - - - -.
: : : :
: list : : :
: +--------+-------+ : : +--------+--------+ +--------+------+ :
: | 0 | 1 | : : .->| 0 | 2 | .->| ////// | //// | :
: | "1/Tag"| o-----+----+-----+-' | "1/Tag"| o-----+-' | "1/Tag"| null | :
: +--------+-------+ : : +--------+--------+ +--------+------+ :
: : : :
: : : :
`- - - - - - - - - - - - -' '- - - - - - - - - - - - - - - - - - - - - - - -'
```

32
src/std/box-recursive.md Normal file
View File

@@ -0,0 +1,32 @@
# Box with Recursive Data Structures
Recursive data types or data types with dynamic sizes need to use a `Box`:
```rust,editable
#[derive(Debug)]
enum List<T> {
Cons(T, Box<List<T>>),
Nil,
}
fn main() {
let list: List<i32> = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Nil))));
println!("{list:?}");
}
```
```bob
Stack Heap
.- - - - - - - - - - - - -. .- - - - - - - - - - - - - - - - - - - - - - - -.
: : : :
: list : : :
: +--------+-------+ : : +--------+--------+ +--------+------+ :
: | Tag | Cons | : : .->| Tag | Cons | .->| Tag | Nil | :
: | 0 | 1 | : : | | 0 | 2 | | | ////// | //// | :
: | 1 | o-----+----+-----+-' | 1 | o------+-' | ////// | //// | :
: +--------+-------+ : : +--------+--------+ +--------+------+ :
: : : :
: : : :
`- - - - - - - - - - - - -' '- - - - - - - - - - - - - - - - - - - - - - - -'
```

30
src/std/box.md Normal file
View File

@@ -0,0 +1,30 @@
# `Box`
[`Box`][1] is an owned pointer to data on the heap:
```rust,editable
fn main() {
let five = Box::new(5);
println!("five: {}", *five);
}
```
```bob
Stack Heap
.- - - - - - -. .- - - - - - -.
: : : :
: five : : :
: +-----+ : : +-----+ :
: | o---|---+-----+-->| 5 | :
: +-----+ : : +-----+ :
: : : :
: : : :
`- - - - - - -' `- - - - - - -'
```
`Box<T>` implements `Deref<Target = T>`, which means that you can [call methods
from `T` directly on a `Box<T>`][2].
[1]: https://doc.rust-lang.org/std/boxed/struct.Box.html
[2]: https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-coercion

26
src/std/hashmap.md Normal file
View File

@@ -0,0 +1,26 @@
# `HashMap`
Standard hash map with protection against HashDoS attacks:
```rust,editable
use std::collections::HashMap;
fn main() {
let mut page_counts = HashMap::new();
page_counts.insert("Adventures of Huckleberry Finn".to_string(), 207);
page_counts.insert("Grimms' Fairy Tales".to_string(), 751);
page_counts.insert("Pride and Prejudice".to_string(), 303);
if !page_counts.contains_key("Les Misérables") {
println!("We've know about {} books, but not Les Misérables.",
page_counts.len());
}
for book in ["Pride and Prejudice", "Alice's Adventure in Wonderland"] {
match page_counts.get(book) {
Some(count) => println!("{book}: {count} pages"),
None => println!("{book} is unknown.")
}
}
}
```

14
src/std/option-result.md Normal file
View File

@@ -0,0 +1,14 @@
# `Option` and `Result`
The types represent optional data:
```rust,editable
fn main() {
let numbers = vec![10, 20, 30];
let first: Option<&i8> = numbers.first();
println!("first: {first:?}");
let idx: Result<usize, usize> = numbers.binary_search(&10);
println!("idx: {idx:?}");
}
```

22
src/std/rc.md Normal file
View File

@@ -0,0 +1,22 @@
# `Rc`
[`Rc`][1] is a reference-counted shared pointer. Use this when you need to refer
to the same data from multiple places:
```rust,editable
use std::rc::Rc;
fn main() {
let mut a = Rc::new(10);
let mut b = a.clone();
println!("a: {a}");
println!("b: {b}");
}
```
If you need to mutate the data inside an `Rc`, you will need to wrap the data in
a type such as [`Cell` or `RefCell`][2].
[1]: https://doc.rust-lang.org/std/rc/struct.Rc.html
[2]: https://doc.rust-lang.org/std/cell/index.html

22
src/std/string.md Normal file
View File

@@ -0,0 +1,22 @@
# String
[`String`][1] is the standard heap-allocated growable UTF-8 string buffer:
```rust,editable
fn main() {
let mut s1 = String::new();
s1.push_str("Hello");
println!("s1: len = {}, capacity = {}", s1.len(), s1.capacity());
let mut s2 = String::with_capacity(s1.len() + 1);
s2.push_str(&s1);
s2.push('!');
println!("s2: len = {}, capacity = {}", s2.len(), s2.capacity());
}
```
`String` implements [`Deref<Target = str>`][2], which means that you can call all
`str` methods on a `String`.
[1]: https://doc.rust-lang.org/std/string/struct.String.html
[2]: https://doc.rust-lang.org/std/string/struct.String.html#deref-methods-str

25
src/std/vec.md Normal file
View File

@@ -0,0 +1,25 @@
# `Vec`
[`Vec`][1] is the standard resizeable heap-allocated buffer:
```rust,editable
fn main() {
let mut numbers = Vec::new();
numbers.push(42);
let mut v1 = Vec::new();
v1.push(42);
println!("v1: len = {}, capacity = {}", v1.len(), v1.capacity());
let mut v2 = Vec::with_capacity(v1.len() + 1);
v2.extend(v1.iter());
v2.push(9999);
println!("v2: len = {}, capacity = {}", v2.len(), v2.capacity());
}
```
`Vec` implements [`Deref<Target = [T]>`][2], which means that you can call slice
methods on a `Vec`.
[1]: https://doc.rust-lang.org/std/vec/struct.Vec.html
[2]: https://doc.rust-lang.org/std/vec/struct.Vec.html#deref-methods-[T]