You've already forked comprehensive-rust
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:
31
src/std/box-niche.md
Normal file
31
src/std/box-niche.md
Normal 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
32
src/std/box-recursive.md
Normal 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
30
src/std/box.md
Normal 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
26
src/std/hashmap.md
Normal 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
14
src/std/option-result.md
Normal 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
22
src/std/rc.md
Normal 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
22
src/std/string.md
Normal 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
25
src/std/vec.md
Normal 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]
|
||||
Reference in New Issue
Block a user