diff --git a/src/enums/sizes.md b/src/enums/sizes.md index 465ef62f..32d2d5b7 100644 --- a/src/enums/sizes.md +++ b/src/enums/sizes.md @@ -65,91 +65,91 @@ Key Points: types](https://doc.rust-lang.org/std/option/#representation), Rust guarantees that `size_of::()` equals `size_of::>()`. -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"); - dbg_bits!(None::, u8); - dbg_bits!(Some(false), u8); - dbg_bits!(Some(true), u8); + println!("Bitwise representation of Option"); + dbg_bits!(None::, u8); + dbg_bits!(Some(false), u8); + dbg_bits!(Some(true), u8); - println!("Bitwise representation of Option>"); - dbg_bits!(Some(Some(false)), u8); - dbg_bits!(Some(Some(true)), u8); - dbg_bits!(Some(None::), u8); - dbg_bits!(None::>, u8); + println!("Bitwise representation of Option>"); + dbg_bits!(Some(Some(false)), u8); + dbg_bits!(Some(Some(true)), u8); + dbg_bits!(Some(None::), u8); + dbg_bits!(None::>, 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::, @@@@@@@@), 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::, @@@@@@@@), u16); + } + } + ``` diff --git a/src/memory-management/stack.md b/src/memory-management/stack.md index bf925497..ab332395 100644 --- a/src/memory-management/stack.md +++ b/src/memory-management/stack.md @@ -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}"); + } } -} -``` + ``` diff --git a/src/pattern-matching/destructuring-arrays.md b/src/pattern-matching/destructuring-arrays.md index 6474a68c..fdf7ec23 100644 --- a/src/pattern-matching/destructuring-arrays.md +++ b/src/pattern-matching/destructuring-arrays.md @@ -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. diff --git a/src/std/hashmap.md b/src/std/hashmap.md index 6fa499b0..c1552a0d 100644 --- a/src/std/hashmap.md +++ b/src/std/hashmap.md @@ -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`, and avoid using `&str` as key to make examples easier. Using references in collections can, of course, be done, diff --git a/src/traits.md b/src/traits.md index dd43e6a9..05ea082d 100644 --- a/src/traits.md +++ b/src/traits.md @@ -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` 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::(), std::mem::size_of::()); - println!("{} {}", std::mem::size_of::<&Dog>(), std::mem::size_of::<&Cat>()); - println!("{}", std::mem::size_of::<&dyn Greet>()); - println!("{}", std::mem::size_of::>()); -``` +* Compare these outputs in the above example: + ```rust,ignore + println!("{} {}", std::mem::size_of::(), std::mem::size_of::()); + println!("{} {}", std::mem::size_of::<&Dog>(), std::mem::size_of::<&Cat>()); + println!("{}", std::mem::size_of::<&dyn Greet>()); + println!("{}", std::mem::size_of::>()); + ```