mirror of
https://github.com/google/comprehensive-rust.git
synced 2024-11-25 17:21:45 +02:00
Indent code in speaker notes (#476)
* Indent code in speaker notes #475 * Update stack.md * Update destructuring-arrays.md * Update hashmap.md * Update traits.md
This commit is contained in:
parent
368f3ba302
commit
59d3d7f625
@ -65,91 +65,91 @@ Key Points:
|
||||
types](https://doc.rust-lang.org/std/option/#representation), Rust guarantees
|
||||
that `size_of::<T>()` equals `size_of::<Option<T>>()`.
|
||||
|
||||
Example code if you want to show how the bitwise representation *may* look like in practice.
|
||||
It's important to note that the compiler provides no guarantees regarding this representation, therefore this is totally unsafe.
|
||||
Example code if you want to show how the bitwise representation *may* look like in practice.
|
||||
It's important to note that the compiler provides no guarantees regarding this representation, therefore this is totally unsafe.
|
||||
|
||||
```rust,editable
|
||||
use std::mem::transmute;
|
||||
```rust,editable
|
||||
use std::mem::transmute;
|
||||
|
||||
macro_rules! dbg_bits {
|
||||
($e:expr, $bit_type:ty) => {
|
||||
println!("- {}: {:#x}", stringify!($e), transmute::<_, $bit_type>($e));
|
||||
};
|
||||
}
|
||||
macro_rules! dbg_bits {
|
||||
($e:expr, $bit_type:ty) => {
|
||||
println!("- {}: {:#x}", stringify!($e), transmute::<_, $bit_type>($e));
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// TOTALLY UNSAFE. Rust provides no guarantees about the bitwise
|
||||
// representation of types.
|
||||
unsafe {
|
||||
println!("Bitwise representation of bool");
|
||||
dbg_bits!(false, u8);
|
||||
dbg_bits!(true, u8);
|
||||
fn main() {
|
||||
// TOTALLY UNSAFE. Rust provides no guarantees about the bitwise
|
||||
// representation of types.
|
||||
unsafe {
|
||||
println!("Bitwise representation of bool");
|
||||
dbg_bits!(false, u8);
|
||||
dbg_bits!(true, u8);
|
||||
|
||||
println!("Bitwise representation of Option<bool>");
|
||||
dbg_bits!(None::<bool>, u8);
|
||||
dbg_bits!(Some(false), u8);
|
||||
dbg_bits!(Some(true), u8);
|
||||
println!("Bitwise representation of Option<bool>");
|
||||
dbg_bits!(None::<bool>, u8);
|
||||
dbg_bits!(Some(false), u8);
|
||||
dbg_bits!(Some(true), u8);
|
||||
|
||||
println!("Bitwise representation of Option<Option<bool>>");
|
||||
dbg_bits!(Some(Some(false)), u8);
|
||||
dbg_bits!(Some(Some(true)), u8);
|
||||
dbg_bits!(Some(None::<bool>), u8);
|
||||
dbg_bits!(None::<Option<bool>>, u8);
|
||||
println!("Bitwise representation of Option<Option<bool>>");
|
||||
dbg_bits!(Some(Some(false)), u8);
|
||||
dbg_bits!(Some(Some(true)), u8);
|
||||
dbg_bits!(Some(None::<bool>), u8);
|
||||
dbg_bits!(None::<Option<bool>>, u8);
|
||||
|
||||
println!("Bitwise representation of Option<&i32>");
|
||||
dbg_bits!(None::<&i32>, usize);
|
||||
dbg_bits!(Some(&0i32), usize);
|
||||
}
|
||||
}
|
||||
```
|
||||
println!("Bitwise representation of Option<&i32>");
|
||||
dbg_bits!(None::<&i32>, usize);
|
||||
dbg_bits!(Some(&0i32), usize);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
More complex example if you want to discuss what happens when we chain more than 256 `Option`s together.
|
||||
More complex example if you want to discuss what happens when we chain more than 256 `Option`s together.
|
||||
|
||||
```rust,editable
|
||||
#![recursion_limit = "1000"]
|
||||
```rust,editable
|
||||
#![recursion_limit = "1000"]
|
||||
|
||||
use std::mem::transmute;
|
||||
use std::mem::transmute;
|
||||
|
||||
macro_rules! dbg_bits {
|
||||
($e:expr, $bit_type:ty) => {
|
||||
println!("- {}: {:#x}", stringify!($e), transmute::<_, $bit_type>($e));
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! dbg_bits {
|
||||
($e:expr, $bit_type:ty) => {
|
||||
println!("- {}: {:#x}", stringify!($e), transmute::<_, $bit_type>($e));
|
||||
};
|
||||
}
|
||||
// Macro to wrap a value in 2^n Some() where n is the number of "@" signs.
|
||||
// Increasing the recursion limit is required to evaluate this macro.
|
||||
macro_rules! many_options {
|
||||
($value:expr) => { Some($value) };
|
||||
($value:expr, @) => {
|
||||
Some(Some($value))
|
||||
};
|
||||
($value:expr, @ $($more:tt)+) => {
|
||||
many_options!(many_options!($value, $($more)+), $($more)+)
|
||||
};
|
||||
}
|
||||
|
||||
// Macro to wrap a value in 2^n Some() where n is the number of "@" signs.
|
||||
// Increasing the recursion limit is required to evaluate this macro.
|
||||
macro_rules! many_options {
|
||||
($value:expr) => { Some($value) };
|
||||
($value:expr, @) => {
|
||||
Some(Some($value))
|
||||
};
|
||||
($value:expr, @ $($more:tt)+) => {
|
||||
many_options!(many_options!($value, $($more)+), $($more)+)
|
||||
};
|
||||
}
|
||||
fn main() {
|
||||
// TOTALLY UNSAFE. Rust provides no guarantees about the bitwise
|
||||
// representation of types.
|
||||
unsafe {
|
||||
assert_eq!(many_options!(false), Some(false));
|
||||
assert_eq!(many_options!(false, @), Some(Some(false)));
|
||||
assert_eq!(many_options!(false, @@), Some(Some(Some(Some(false)))));
|
||||
|
||||
fn main() {
|
||||
// TOTALLY UNSAFE. Rust provides no guarantees about the bitwise
|
||||
// representation of types.
|
||||
unsafe {
|
||||
assert_eq!(many_options!(false), Some(false));
|
||||
assert_eq!(many_options!(false, @), Some(Some(false)));
|
||||
assert_eq!(many_options!(false, @@), Some(Some(Some(Some(false)))));
|
||||
println!("Bitwise representation of a chain of 128 Option's.");
|
||||
dbg_bits!(many_options!(false, @@@@@@@), u8);
|
||||
dbg_bits!(many_options!(true, @@@@@@@), u8);
|
||||
|
||||
println!("Bitwise representation of a chain of 128 Option's.");
|
||||
dbg_bits!(many_options!(false, @@@@@@@), u8);
|
||||
dbg_bits!(many_options!(true, @@@@@@@), u8);
|
||||
println!("Bitwise representation of a chain of 256 Option's.");
|
||||
dbg_bits!(many_options!(false, @@@@@@@@), u16);
|
||||
dbg_bits!(many_options!(true, @@@@@@@@), u16);
|
||||
|
||||
println!("Bitwise representation of a chain of 256 Option's.");
|
||||
dbg_bits!(many_options!(false, @@@@@@@@), u16);
|
||||
dbg_bits!(many_options!(true, @@@@@@@@), u16);
|
||||
|
||||
println!("Bitwise representation of a chain of 257 Option's.");
|
||||
dbg_bits!(many_options!(Some(false), @@@@@@@@), u16);
|
||||
dbg_bits!(many_options!(Some(true), @@@@@@@@), u16);
|
||||
dbg_bits!(many_options!(None::<bool>, @@@@@@@@), u16);
|
||||
}
|
||||
}
|
||||
```
|
||||
println!("Bitwise representation of a chain of 257 Option's.");
|
||||
dbg_bits!(many_options!(Some(false), @@@@@@@@), u16);
|
||||
dbg_bits!(many_options!(Some(true), @@@@@@@@), u16);
|
||||
dbg_bits!(many_options!(None::<bool>, @@@@@@@@), u16);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
@ -31,20 +31,20 @@ fn main() {
|
||||
|
||||
* We can inspect the memory layout with `unsafe` code. However, you should point out that this is rightfully unsafe!
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let mut s1 = String::from("Hello");
|
||||
s1.push(' ');
|
||||
s1.push_str("world");
|
||||
// DON'T DO THIS AT HOME! For educational purposes only.
|
||||
// String provides no guarantees about its layout, so this could lead to
|
||||
// undefined behavior.
|
||||
unsafe {
|
||||
let (capacity, ptr, len): (usize, usize, usize) = std::mem::transmute(s1);
|
||||
println!("ptr = {ptr:#x}, len = {len}, capacity = {capacity}");
|
||||
```rust,editable
|
||||
fn main() {
|
||||
let mut s1 = String::from("Hello");
|
||||
s1.push(' ');
|
||||
s1.push_str("world");
|
||||
// DON'T DO THIS AT HOME! For educational purposes only.
|
||||
// String provides no guarantees about its layout, so this could lead to
|
||||
// undefined behavior.
|
||||
unsafe {
|
||||
let (capacity, ptr, len): (usize, usize, usize) = std::mem::transmute(s1);
|
||||
println!("ptr = {ptr:#x}, len = {len}, capacity = {capacity}");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
@ -12,22 +12,22 @@ You can destructure arrays, tuples, and slices by matching on their elements:
|
||||
* Destructuring of slices of unknown length also works with patterns of fixed length.
|
||||
|
||||
|
||||
```rust,editable
|
||||
fn main() {
|
||||
inspect(&[0, -2, 3]);
|
||||
inspect(&[0, -2, 3, 4]);
|
||||
}
|
||||
```rust,editable
|
||||
fn main() {
|
||||
inspect(&[0, -2, 3]);
|
||||
inspect(&[0, -2, 3, 4]);
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn inspect(slice: &[i32]) {
|
||||
println!("Tell me about {slice:?}");
|
||||
match slice {
|
||||
&[0, y, z] => println!("First is 0, y = {y}, and z = {z}"),
|
||||
&[1, ..] => println!("First is 1 and the rest were ignored"),
|
||||
_ => println!("All elements were ignored"),
|
||||
}
|
||||
}
|
||||
```
|
||||
#[rustfmt::skip]
|
||||
fn inspect(slice: &[i32]) {
|
||||
println!("Tell me about {slice:?}");
|
||||
match slice {
|
||||
&[0, y, z] => println!("First is 0, y = {y}, and z = {z}"),
|
||||
&[1, ..] => println!("First is 1 and the rest were ignored"),
|
||||
_ => println!("All elements were ignored"),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Create a new pattern using `_` to represent an element.
|
||||
* Add more values to the array.
|
||||
|
@ -38,23 +38,23 @@ fn main() {
|
||||
* `HashMap` is not defined in the prelude and needs to be brought into scope.
|
||||
* Try the following lines of code. The first line will see if a book is in the hashmap and if not return an alternative value. The second line will insert the alternative value in the hashmap if the book is not found.
|
||||
|
||||
```rust,ignore
|
||||
let pc1 = page_counts
|
||||
.get("Harry Potter and the Sorcerer's Stone ")
|
||||
.unwrap_or(&336);
|
||||
let pc2 = page_counts
|
||||
.entry("The Hunger Games".to_string())
|
||||
.or_insert(374);
|
||||
```
|
||||
```rust,ignore
|
||||
let pc1 = page_counts
|
||||
.get("Harry Potter and the Sorcerer's Stone ")
|
||||
.unwrap_or(&336);
|
||||
let pc2 = page_counts
|
||||
.entry("The Hunger Games".to_string())
|
||||
.or_insert(374);
|
||||
```
|
||||
* Unlike `vec!`, there is unfortunately no standard `hashmap!` macro.
|
||||
* Although, since Rust 1.56, HashMap implements [`From<[(K, V); N]>`][1], which allows us to easily initialize a hash map from a literal array:
|
||||
|
||||
```rust,ignore
|
||||
let page_counts = HashMap::from([
|
||||
("Harry Potter and the Sorcerer's Stone".to_string(), 336),
|
||||
("The Hunger Games".to_string(), 374),
|
||||
]);
|
||||
```
|
||||
```rust,ignore
|
||||
let page_counts = HashMap::from([
|
||||
("Harry Potter and the Sorcerer's Stone".to_string(), 336),
|
||||
("The Hunger Games".to_string(), 374),
|
||||
]);
|
||||
```
|
||||
|
||||
* Alternatively HashMap can be built from any `Iterator` which yields key-value tuples.
|
||||
* We are showing `HashMap<String, i32>`, and avoid using `&str` as key to make examples easier. Using references in collections can, of course, be done,
|
||||
|
@ -42,13 +42,12 @@ fn main() {
|
||||
* Types that implement a given trait may be of different sizes. This makes it impossible to have things like `Vec<Greet>` in the example above.
|
||||
* `dyn Greet` is a way to tell the compiler about a dynamically sized type that implements `Greet`.
|
||||
* In the example, `pets` holds Fat Pointers to objects that implement `Greet`. The Fat Pointer consists of two components, a pointer to the actual object and a pointer to the virtual method table for the `Greet` implementation of that particular object.
|
||||
|
||||
Compare these outputs in the above example:
|
||||
```rust,ignore
|
||||
println!("{} {}", std::mem::size_of::<Dog>(), std::mem::size_of::<Cat>());
|
||||
println!("{} {}", std::mem::size_of::<&Dog>(), std::mem::size_of::<&Cat>());
|
||||
println!("{}", std::mem::size_of::<&dyn Greet>());
|
||||
println!("{}", std::mem::size_of::<Box<dyn Greet>>());
|
||||
```
|
||||
* Compare these outputs in the above example:
|
||||
```rust,ignore
|
||||
println!("{} {}", std::mem::size_of::<Dog>(), std::mem::size_of::<Cat>());
|
||||
println!("{} {}", std::mem::size_of::<&Dog>(), std::mem::size_of::<&Cat>());
|
||||
println!("{}", std::mem::size_of::<&dyn Greet>());
|
||||
println!("{}", std::mem::size_of::<Box<dyn Greet>>());
|
||||
```
|
||||
|
||||
</details>
|
||||
|
Loading…
Reference in New Issue
Block a user