1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-07-12 01:00:16 +02:00

Use a terser style on slides. Avoid footnotes

This commit is contained in:
LukeMathWalker
2025-07-02 17:16:42 +02:00
parent ac219256b5
commit edfe9e8348
2 changed files with 27 additions and 28 deletions

View File

@ -4,15 +4,15 @@ minutes: 5
# Leveraging the Type System # Leveraging the Type System
Rust's type system is _expressive_.\ Rust's type system is _expressive_: you can use types and traits to build
We can use types and traits to build abstractions that make our code harder to abstractions that make your code harder to misuse.
misuse. In some cases, we can even go as far as enforcing correctness at
_compile-time_. Quite often, these abstractions have no runtime
overhead[^zero-cost].
The type system can also be used to model concepts and constraints from your In some cases, you can go as far as enforcing correctness at _compile-time_,
business domain. By designing our types carefully, we can improve the clarity with no runtime overhead.
and maintainability of the entire codebase.
Types and traits can model concepts and constraints from your business domain.
With careful design, you can improve the clarity and maintainability of the
entire codebase.
<details> <details>
@ -36,12 +36,12 @@ Additional items speaker may mention:
doesn't support inheritance, and object boundaries must be mindful of the doesn't support inheritance, and object boundaries must be mindful of the
constraints introduced by the borrow-checker. constraints introduced by the borrow-checker.
- Mention that type-level abstractions are often referred to as "zero-cost
abstractions", although the label can be misleading: the impact on compile
times and code complexity may be significant.
</details> </details>
{{%segment outline}} {{%segment outline}}
[1]: https://pragprog.com/titles/swdddf/domain-modeling-made-functional/ [1]: https://pragprog.com/titles/swdddf/domain-modeling-made-functional/
[^zero-cost]: They often referred to as "zero-cost abstractions", although the
label can be misleading: the impact on compile times and code complexity may
be significant.

View File

@ -36,27 +36,26 @@ impl Username {
- The newtype pattern, combined with Rust's module and visibility system, can be - The newtype pattern, combined with Rust's module and visibility system, can be
used to _guarantee_ that instances of a given type satisfy a set of used to _guarantee_ that instances of a given type satisfy a set of
invariants.\ invariants.\
In the example above, the raw `String` stored inside the In the example above, the raw `String` stored inside the `Username` struct
`Username` struct can't be accessed directly from other modules or crates, can't be accessed directly from other modules or crates, since it's not marked
since it's not marked as `pub` or `pub(in ...)`. Consumers of the `Username` as `pub` or `pub(in ...)`. Consumers of the `Username` type are forced to use
type are forced to use the `new` method to create instances. In turn, `new` the `new` method to create instances. In turn, `new` performs validation, thus
performs validation, thus ensuring that all instances of `Username` satisfy ensuring that all instances of `Username` satisfy those checks.
those checks.
- The `as_str` method allows consumers to access the raw string representation - The `as_str` method allows consumers to access the raw string representation
(e.g. to store it in a database) but, thanks to Rust's borrow checker, (e.g. to store it in a database) but, thanks to Rust's borrow checker, they
they can't modify it. can't modify it.
- Stress the importance of evaluating _the entire API surface_ exposed by a newtype - Stress the importance of evaluating _the entire API surface_ exposed by a
to determine if invariants are indeed bullet-proof.\ newtype to determine if invariants are indeed bullet-proof.\
It is crucial to consider all possible interactions, including trait implementations, It is crucial to consider all possible interactions, including trait
that may allow users to bypass the invariants. For example, if the `Username` implementations, that may allow users to bypass the invariants. For example,
type implements the `DerefMut` trait, users can modify the underlying string if the `Username` type implements the `DerefMut` trait, users can modify the
directly, bypassing the validation checks in `new`. underlying string directly, bypassing the validation checks in `new`.
- Type-level invariants have second-order benefits.\ - Type-level invariants have second-order benefits.\
The input is validated once, at the boundary, and the rest of the program can rely The input is validated once, at the boundary, and the rest of the program can
on the invariants being upheld. We can avoid redundant validation and rely on the invariants being upheld. We can avoid redundant validation and
"defensive programming" checks throughout the program, reducing noise and "defensive programming" checks throughout the program, reducing noise and
improving performance. improving performance.