1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2026-03-05 21:06:44 +02:00
Files
comprehensive-rust/book.toml
Nicole L 0a017e5b95 Rework lifetimes section (#2964)
This PR attempts to rework the lifetimes section to better contextualize
how lifetimes are used and to try to lead through a series of examples
more naturally. I think the current version of the lifetimes section
falls short in a handful of ways that make it hard to teach in class.
For a long time I've been experimenting with different ways to discuss
the topic, and in my recent classes I think I've finally hit on an
approach that works. The changes in this PR capture the approach I've
been using.

The core idea is to contextualize lifetime annotations by looking at
what happens when we return a reference from a function. We start with a
simple example that doesn't return a reference to show that the borrow
ends when the function returns. Then we look at a function that returns
a reference and show that it extends the borrow that was passed into the
function. With that context, we then look at cases where we need
lifetime annotations, specifically examples where there are two ref
arguments and a returned ref. We look at both possible cases: A function
where either of the argument refs may be returned, and a case where only
one will be returned. In both cases we show how we use lifetime
annotations to tell the compiler what the returned ref is borrowing.

I haven't had a chance to use these slides in class yet so I'm putting
this up as a draft PR while I continue to iterate on it so that other
folks can start giving feedback.
2025-10-31 19:37:53 +00:00

313 lines
16 KiB
TOML

[book]
authors = ["Martin Geisler"]
language = "en"
src = "src"
title = "Comprehensive Rust 🦀"
[rust]
edition = "2024"
[build]
extra-watch-dirs = ["po", "third_party"]
[preprocessor.gettext]
after = ["links"]
[preprocessor.svgbob]
renderers = ["html"]
after = ["gettext"]
class = "bob"
[preprocessor.course]
verbose = false # Report timing information.
[output.xgettext]
optional = true
pot-file = "messages.pot"
granularity = 0
[output.pandoc]
optional = true
disabled = true
hosted-html = "https://google.github.io/comprehensive-rust/"
[output.pandoc.profile.pdf]
output-file = "comprehensive-rust.pdf"
pdf-engine = "lualatex"
[output.pandoc.profile.pdf.variables]
mainfont = "Noto Serif"
sansfont = "Noto Sans"
monofont = "Noto Sans Mono"
mainfontfallback = [
"NotoColorEmoji:mode=harf",
"NotoNaskhArabic:",
]
sansfontfallback = [
"NotoSansArabic:",
]
monofontfallback = [
"NotoColorEmoji:mode=harf",
"NotoSansMath:",
"NotoSansMonoCJKSC:",
"NotoSansArabic:",
]
geometry = ["margin=1.25in"]
linkcolor = "blue"
urlcolor = "red"
[output.html]
smart-punctuation = true
additional-js = [
"theme/speaker-notes.js",
"theme/redbox.js",
]
additional-css = [
"theme/css/svgbob.css",
"theme/css/redbox.css",
"theme/css/speaker-notes.css",
"theme/css/language-picker.css",
"theme/css/rtl.css",
]
site-url = "/comprehensive-rust/"
git-repository-url = "https://github.com/google/comprehensive-rust"
edit-url-template = "https://github.com/google/comprehensive-rust/edit/main/{path}"
[output.html.fold]
enable = true
level = 0
[output.html.playground]
editable = true
line-numbers = true
[output.html.search]
use-boolean-and = true
# Redirects in the form of "old-path" = "new-path", where the new path
# is relative to the old path.
#
# Please keep the table sorted and avoid multi-step redirects.
[output.html.redirect]
"async/async-await.html" = "../concurrency/async/async-await.html"
"async/channels.html" = "../concurrency/async-control-flow/channels.html"
"async/concurrency/channels.html" = "../channels.html"
"async/control-flow/join.html" = "../concurrency/async-control-flow/join.html"
"async/control-flow/select.html" = "../concurrency/async-control-flow/select.html"
"async/futures.html" = "../concurrency/async/futures.html"
"async.html" = "concurrency/welcome-async.html"
"async/pitfall/async-traits.html" = "../async-pitfalls/async-traits.html"
"async/pitfalls/async-traits.html" = "../concurrency/async-pitfalls/async-traits.html"
"async/pitfalls/blocking-executor.html" = "../concurrency/async-pitfalls/blocking-executor.html"
"async/pitfalls/cancellation.html" = "../concurrency/async-pitfalls/cancellation.html"
"async/pitfalls.html" = "../concurrency/async-pitfalls.html"
"async/pitfalls/pin.html" = "../concurrency/async-pitfalls/pin.html"
"async/runtimes.html" = "../concurrency/async/runtimes.html"
"async/runtimes/tokio.html" = "../concurrency/async/runtimes/tokio.html"
"async/tasks.html" = "../concurrency/async/tasks.html"
"basic-syntax/compound-types.html" = "../tuples-and-arrays/tuples-and-arrays.html"
"basic-syntax/functions.html" = "../control-flow-basics/functions.html"
"basic-syntax/functions-interlude.html" = "../control-flow-basics/functions.html"
"basic-syntax.html" = "control-flow-basics.html"
"basic-syntax/methods.html" = "../control-flow-basics/functions.html"
"basic-syntax/references-dangling.html" = "../references/shared.html"
"basic-syntax/references.html" = "../references/shared.html"
"basic-syntax/rustdoc.html" = "../std-types/docs.html"
"basic-syntax/scalar-types.html" = "../types-and-values/values.html"
"basic-syntax/scopes-shadowing.html" = "../control-flow-basics/blocks-and-scopes.html"
"basic-syntax/slices.html" = "../references/slices.html"
"basic-syntax/static-and-const.html" = "../unsafe-rust/static-and-const.html"
"basic-syntax/string-slices.html" = "../references/strings.html"
"basic-syntax/type-inference.html" = "../types-and-values/inference.html"
"basic-syntax/variables.html" = "../types-and-values/variables.html"
"concurrency.html" = "concurrency/welcome.html"
"concurrency/scoped-threads.html" = "threads/scoped.html"
"concurrency/shared_state/arc.html" = "../shared-state/arc.html"
"concurrency/shared_state/example.html" = "../shared-state/example.html"
"concurrency/shared_state.html" = "shared-state.html"
"concurrency/shared_state/mutex.html" = "../shared-state/mutex.html"
"control-flow-basics/conditionals.html" = "if.html"
"control-flow/blocks.html" = "../control-flow-basics/blocks-and-scopes.html"
"control-flow/break-continue.html" = "../control-flow-basics/break-continue.html"
"control-flow/for-expressions.html" = "../control-flow-basics/loops.html"
"control-flow.html" = "control-flow-basics.html"
"control-flow/if-expressions.html" = "../control-flow-basics/conditionals.html"
"control-flow/if-let-expressions.html" = "../pattern-matching/let-control-flow.html"
"control-flow/loop-expressions.html" = "../control-flow-basics/loops.html"
"control-flow/match-expressions.html" = "../tuples-and-arrays/match.html"
"control-flow/novel.html" = "../pattern-matching/let-control-flow.html"
"control-flow/while-expressions.html" = "../control-flow-basics/loops.html"
"control-flow/while-let-expression.html" = "while-let-expressions.html"
"control-flow/while-let-expressions.html" = "../pattern-matching/let-control-flow.html"
"enums.html" = "user-defined-types/enums.html"
"enums/sizes.html" = "../user-defined-types/enums.html"
"enums/variant-payloads.html" = "../user-defined-types/enums.html"
"error-handling/converting-error-types-example.html" = "../error-handling/try-conversions.html"
"error-handling/converting-error-types.html" = "../error-handling/try-conversions.html"
"error-handling/deriving-error-enums.html" = "../error-handling/error.html"
"error-handling/dynamic-errors.html" = "../error-handling/anyhow.html"
"error-handling/error-contexts.html" = "../error-handling/anyhow.html"
"error-handling/thiserror-and-anyhow.html" = "../error-handling/anyhow.html"
"error-handling/panic-unwind.html" = "../error-handling/panics.html"
"error-handling/try-operator.html" = "../error-handling/try.html"
"exercises/concurrency/afternoon.html" = "../../concurrency/async-exercises.html"
"exercises/concurrency/chat-app.html" = "../../concurrency/async-exercises/chat-app.html"
"exercises/concurrency/dining-philosophers-async.html" = "../../concurrency/async-exercises/dining-philosophers.html"
"exercises/concurrency/dining-philosophers.html" = "../../concurrency/sync-exercises/dining-philosophers.html"
"exercises/concurrency/elevator.html" = "chat-app.html"
"exercises/concurrency/link-checker.html" = "../../concurrency/sync-exercises/link-checker.html"
"exercises/concurrency/morning.html" = "../../concurrency/sync-exercises.html"
"exercises/concurrency/solutions-afternoon.html" = "../../concurrency/async-exercises/solutions.html"
"exercises/concurrency/solutions-morning.html" = "../../concurrency/sync-exercises/solutions.html"
"exercises/day-1/afternoon.html" = "../../control-flow-basics/exercise.html"
"exercises/day-1/book-library.html" = "../day-2/book-library.html"
"exercises/day-1/for-loops.html" = "../../tuples-and-arrays/exercise.html"
"exercises/day-1/implicit-conversions.html" = "../../std-traits/exercise.html"
"exercises/day-1/iterators-and-ownership.html" = "../day-2/iterators-and-ownership.html"
"exercises/day-1/luhn.html" = "../../testing/exercise.html"
"exercises/day-1/morning.html" = "../../control-flow-basics/exercise.html"
"exercises/day-1/pattern-matching.html" = "../../user-defined-types/exercise.html"
"exercises/day-1/soluções-tarde.html" = "solutions-afternoon.html"
"exercises/day-2/afternoon.html" = "../../control-flow-basics/exercise.html"
"exercises/day-2/book-library.html" = "../../std-types/exercise.html"
"exercises/day-2/health-statistics.html" = "../../borrowing/exercise.html"
"exercises/day-2/iterators-and-ownership.html" = "../../iterators/intoiterator.html"
"exercises/day-2/luhn.html" = "../day-1/luhn.html"
"exercises/day-2/morning.html" = "../../control-flow-basics/exercise.html"
"exercises/day-2/points-polygons.html" = "../day-3/points-polygons.html"
"exercises/day-2/soluções-tarde.html" = "solutions-afternoon.html"
"exercises/day-2/strings-iterators.html" = "../../iterators/exercise.html"
"exercises/day-3/afternoon.html" = "../../control-flow-basics/exercise.html"
"exercises/day-3/morning.html" = "../../control-flow-basics/exercise.html"
"exercises/day-3/points-polygons.html" = "../../references/exercise.html"
"exercises/day-3/safe-ffi-wrapper.html" = "../../unsafe-rust/exercise.html"
"exercises/day-3/simple-gui.html" = "../../methods-and-traits/exercise.html"
"exercises/day-3/simples-gui.html" = "simple-gui.html"
"exercises/day-3/soluções-tarde.html" = "solutions-afternoon.html"
"exercises/day-4/afternoon.html" = "../android/morning.html"
"exercises/day-4/android.html" = "../android/morning.html"
"exercises/day-4/dining-philosophers.html" = "../concurrency/dining-philosophers.html"
"exercises/day-4/elevator.html" = "../concurrency/elevator.html"
"exercises/day-4/link-checker.html" = "../concurrency/link-checker.html"
"exercises/day-4/morning.html" = "../concurrency/morning.html"
"exercises/day-4/solutions-morning.html" = "../concurrency/solutions-morning.html"
"generics/closures.html" = "../traits/closures.html"
"generics/data-types.html" = "../generics/generic-data.html"
"generics/methods.html" = "../generics/generic-data.html"
"generics/monomorphization.html" = "../generics/generic-functions.html"
"generics/trait-objects.html" = "../traits/trait-objects.html"
"hello-world/basic-syntax/functions-interlude.html" = "../../control-flow-basics/functions.html"
"hello-world/hello-world.html" = "../types-and-values/hello-world.html"
"lifetimes/lifetime-annotations.html" = "../lifetimes.html"
"memory-management/manual.html" = "../memory-management/approaches.html"
"memory-management/rust.html" = "../memory-management/ownership.html"
"memory-management/scope-based.html" = "../memory-management/approaches.html"
"memory-management/stack.html" = "../memory-management/review.html"
"memory-management/stack-vs-heap.html" = "../memory-management/review.html"
"methods-and-traits/trait-objects.html" = "../smart-pointers/trait-objects.html"
"methods/example.html" = "../methods-and-traits/methods.html"
"methods.html" = "methods-and-traits/methods.html"
"methods/receiver.html" = "../methods-and-traits/methods.html"
"outros-recursos.html" = "other-resources.html"
"ownership/borrowing.html" = "../borrowing/shared.html"
"ownership/copy-clone.html" = "../memory-management/copy-types.html"
"ownership/double-free-modern-cpp.html" = "../memory-management/move.html"
"ownership.html" = "memory-management/ownership.html"
"ownership/lifetimes-data-structures.html" = "../lifetimes/struct-lifetimes.html"
"ownership/lifetimes-function-calls.html" = "../lifetimes/lifetime-elision.html"
"ownership/lifetimes.html" = "../lifetimes/lifetime-annotations.html"
"ownership/moved-strings-rust.html" = "../memory-management/move.html"
"ownership/move-semantics.html" = "../memory-management/move.html"
"ownership/moves-function-calls.html" = "../memory-management/move.html"
"ownership/shared-unique-borrows.html" = "../borrowing/shared.html"
"pattern-matching/destructuring-arrays.html" = "../tuples-and-arrays/destructuring.html"
"pattern-matching/destructuring.html" = "destructuring-structs.html"
"pattern-matching/match-guards.html" = "../tuples-and-arrays/match.html"
"running-the-course/day-4.html" = "course-structure.html"
"sintaxe-básica/funções-interlude.html" = "../basic-syntax/functions-interlude.html"
"slices-and-lifetimes/exercise.html" = "../lifetimes/exercise.html"
"slices-and-lifetimes.html" = "lifetimes.html"
"slices-and-lifetimes/lifetime-annotations.html" = "../lifetimes/lifetime-annotations.html"
"slices-and-lifetimes/lifetime-elision.html" = "../lifetimes/lifetime-elision.html"
"slices-and-lifetimes/slices.html" = "../references/slices.html"
"slices-and-lifetimes/solution.html" = "../lifetimes/solution.html"
"slices-and-lifetimes/str.html" = "../references/strings.html"
"slices-and-lifetimes/struct-lifetimes.html" = "../lifetimes/struct-lifetimes.html"
"std/box.html" = "../smart-pointers/box.html"
"std/box-niche.html" = "../smart-pointers/box.html"
"std/box-recursive.html" = "../smart-pointers/box.html"
"std/cell.html" = "../borrowing/interior-mutability.html"
"std/hashmap.html" = "../std-types/hashmap.html"
"std.html" = "std-types/std.html"
"std/option-result.html" = "../std-types/option.html"
"std/rc.html" = "../smart-pointers/rc.html"
"std/string.html" = "../std-types/string.html"
"std/vec.html" = "../std-types/vec.html"
"structs/field-shorthand.html" = "../user-defined-types/named-structs.html"
"structs.html" = "user-defined-types/named-structs.html"
"structs/tuple-structs.html" = "../user-defined-types/tuple-structs.html"
"structure.html" = "running-the-course/course-structure.html"
"testing/doc-tests.html" = "../testing/other.html"
"testing/googletest.html" = "../android/testing/googletest.html"
"testing/integration-tests.html" = "../testing/other.html"
"testing/mockall.html" = "../android/testing/mockall.html"
"testing/useful-crates.html" = "../testing.html"
"traits/closures.html" = "../std-traits/closures.html"
"traits/default.html" = "../std-traits/default.html"
"traits/default-methods.html" = "../methods-and-traits/traits.html"
"traits/deriving-traits.html" = "../methods-and-traits/deriving.html"
"traits/drop.html" = "../memory-management/drop.html"
"traits/from-into.html" = "../std-traits/from-and-into.html"
"traits/from-iterator.html" = "../iterators/fromiterator.html"
"traits.html" = "methods-and-traits/traits.html"
"traits/impl-trait.html" = "../generics/impl-trait.html"
"traits/important-traits.html" = "../std-traits/comparisons.html"
"traits/iterator.html" = "../iterators/iterators.html"
"traits/operators.html" = "../std-traits/operators.html"
"traits/read-write.html" = "../std-traits/read-and-write.html"
"traits/trait-bounds.html" = "../generics/trait-bounds.html"
"traits/trait-objects.html" = "../smart-pointers/trait-objects.html"
"tuples-and-arrays/match.html" = "../pattern-matching/match.html"
"tuples-and-arrays/tuples-and-arrays.html" = "tuples.html"
"types-and-values/strings.html" = "../references/strings.html"
"unsafe/calling-unsafe-functions.html" = "../unsafe-rust/unsafe-functions.html"
"unsafe/extern-functions.html" = "../unsafe-rust/unsafe-functions.html"
"unsafe.html" = "unsafe-rust/unsafe.html"
"unsafe/mutable-static-variables.html" = "../unsafe-rust/mutable-static.html"
"unsafe/mutable-static-variables.md" = "mutable-static-variables.html"
"unsafe/raw-pointers.html" = "../unsafe-rust/dereferencing.html"
"unsafe/unions.html" = "../unsafe-rust/unions.html"
"unsafe/unsafe-functions.html" = "calling-unsafe-functions.html"
"unsafe/unsafe-traits.html" = "../unsafe-rust/unsafe-traits.html"
"unsafe/writing-unsafe-functions.html" = "../unsafe-rust/unsafe-functions.html"
"user-defined-types/static-and-const.html" = "../user-defined-types/static.html"
"welcome-bare-metal.html" = "bare-metal.html"
"welcome-day-1/what-is-rust.html" = "../hello-world/what-is-rust.html"
"welcome.html" = "./"
"why-rust/an-example-in-c.html" = "../hello-world/example.html"
"why-rust/compile-time.html" = "../hello-world/benefits.html"
"why-rust.html" = "hello-world/benefits.html"
"why-rust/modern.html" = "../hello-world/benefits.html"
"why-rust/runtime.html" = "../hello-world/benefits.html"
[output.exerciser]
output-directory = "comprehensive-rust-exercises"
[output.linkcheck]
optional = true
follow-web-links = false # change to true to check web links
exclude = [
"comprehensive-rust.pdf",
"comprehensive-rust-exercises.zip",
# "crates.io", # uncomment when follow-web-links is true
]
[output.linkcheck2]
optional = true
follow-web-links = false # change to true to check web links
exclude = [
"comprehensive-rust.pdf",
"comprehensive-rust-exercises.zip",
# "crates.io", # uncomment when follow-web-links is true
]