1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-03-27 08:15:40 +02:00
Dustin J. Mitchell 9f9f845acc
Break closures into its own segment ()
In teaching the course last week, we broke here, partly due to time
constraints, but partly because this is a pretty mind-bending topic to
tackle at the end of an information-dense day. A break helps, and
spreading the content over a few slides helps as well.

By the timings in the course, this leaves day 2 looking like

*Fundamentals // Day 2 Morning*
_1 hour and 55 minutes: (1 hour and 10 minutes short)_

* Welcome - _3 minutes_
* Pattern Matching - _45 minutes_
* Methods and Traits - _50 minutes_

*Fundamentals // Day 2 Afternoon*
_3 hours and 30 minutes ( *30 minutes too long*)_

* Welcome - _0 minutes_
* Generics - _45 minutes_
* Standard Library Types - _1 hour_
* Standard Library Traits - _1 hour_
* Closures - _20 minutes_

Maybe we should move generics to the morning session?
2025-01-23 09:32:59 +01:00

1.4 KiB

minutes
5

Capturing

A closure can capture variables from the environment where it was defined.

fn main() {
    let max_value = 5;
    let clamp = |v| {
        if v > max_value {
            max_value
        } else {
            v
        }
    };
    println!(
        "clamped values at {max_value}: {:?}",
        (0..10).map(clamp).collect::<Vec<_>>()
    );
}
  • By default, a closure captures values by reference. Here max_value is captured by clamp, but still available to main for printing. Try making max_value mutable, changing it, and printing the clamped values again. Why doesn't this work?

  • If a closure mutates values, it will capture them by mutable reference. Try adding max_value += 1 to clamp.

  • You can force a closure to move values instead of referencing them with the move keyword. This can help with lifetimes, for example if the closure must outlive the captured values (more on lifetimes later).

    This looks like move |v| ... Try adding this keyword and see if main can still access max_value after defining clamp.

  • By default, closures will capture each variable from an outer scope by the least demanding form of access they can (by shared reference if possible, then exclusive reference, then by move). The move keyword forces capture by value.