mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-05-15 07:06:52 +02:00
Reduce references to niche optimization (#2385)
Niche optimization is currently mentioned in three places: - Enums (User-Defined Types, Day 1 Afternoon) - Option (Standard Library Types, Day 2 Afternoon) - Box (Smart Pointers, Day 3 Morning) This is a tricky thing to get right, and it was just in the speaker notes in each place. #1820 will introduce a fuller explanation. Fixes #1820.
This commit is contained in:
parent
a699430741
commit
d9e3ad9e63
@ -32,7 +32,7 @@ fn main() {
|
|||||||
from `T` directly on a `Box<T>`](https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-coercion).
|
from `T` directly on a `Box<T>`](https://doc.rust-lang.org/std/ops/trait.Deref.html#more-on-deref-coercion).
|
||||||
|
|
||||||
Recursive data types or data types with dynamic sizes cannot be stored inline
|
Recursive data types or data types with dynamic sizes cannot be stored inline
|
||||||
without a pointer indirection, which can be worked around using `Box`:
|
without a pointer indirection. `Box` accomplishes that indirection:
|
||||||
|
|
||||||
```rust,editable
|
```rust,editable
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -86,36 +86,8 @@ fn main() {
|
|||||||
have to use indirection, a `Box` or reference of some kind, instead of storing
|
have to use indirection, a `Box` or reference of some kind, instead of storing
|
||||||
the value directly.
|
the value directly.
|
||||||
|
|
||||||
# More to Explore
|
- Though `Box` looks like `std::unique_ptr` in C++, it cannot be empty/null.
|
||||||
|
This makes `Box` one of the types that allow the compiler to optimize storage
|
||||||
## Niche Optimization
|
of some enums (the "niche optimization").
|
||||||
|
|
||||||
Though `Box` looks like `std::unique_ptr` in C++, it cannot be empty/null. This
|
|
||||||
makes `Box` one of the types that allow the compiler to optimize storage of some
|
|
||||||
enums.
|
|
||||||
|
|
||||||
For example, `Option<Box<T>>` has the same size, as just `Box<T>`, because
|
|
||||||
compiler uses NULL-value to discriminate variants instead of using explicit tag
|
|
||||||
(["Null Pointer Optimization"](https://doc.rust-lang.org/std/option/#representation)):
|
|
||||||
|
|
||||||
```rust,editable
|
|
||||||
use std::mem::size_of_val;
|
|
||||||
|
|
||||||
struct Item(String);
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let just_box: Box<Item> = Box::new(Item("Just box".into()));
|
|
||||||
let optional_box: Option<Box<Item>> =
|
|
||||||
Some(Box::new(Item("Optional box".into())));
|
|
||||||
let none: Option<Box<Item>> = None;
|
|
||||||
|
|
||||||
assert_eq!(size_of_val(&just_box), size_of_val(&optional_box));
|
|
||||||
assert_eq!(size_of_val(&just_box), size_of_val(&none));
|
|
||||||
|
|
||||||
println!("Size of just_box: {}", size_of_val(&just_box));
|
|
||||||
println!("Size of optional_box: {}", size_of_val(&optional_box));
|
|
||||||
println!("Size of none: {}", size_of_val(&none));
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
@ -30,7 +30,11 @@ fn main() {
|
|||||||
None.
|
None.
|
||||||
- It's common to `unwrap`/`expect` all over the place when hacking something
|
- It's common to `unwrap`/`expect` all over the place when hacking something
|
||||||
together, but production code typically handles `None` in a nicer fashion.
|
together, but production code typically handles `None` in a nicer fashion.
|
||||||
- The niche optimization means that `Option<T>` often has the same size in
|
|
||||||
memory as `T`.
|
- The "niche optimization" means that `Option<T>` often has the same size in
|
||||||
|
memory as `T`, if there is some representation that is not a valid value of T.
|
||||||
|
For example, a reference cannot be NULL, so `Option<&T>` automatically uses
|
||||||
|
NULL to represent the `None` variant, and thus can be stored in the same
|
||||||
|
memory as `&T`.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user