Intro to Iterators and Closures

Iterators and Closures

  • Basic iterators

  • Basic closures

  • The full story is much complicated; we will cover it extensively later in the course

Iterators

  • Value that lazily produces values via a .next() method. The .next() method returns an Option: Some while the iterator is still running, None when it is done

  • Obvious example is via the .. operator:

     let mut i = 0..3;
     while let Some(n) = i.next() {
         println!("{}", n);
     }
    

    This is exactly the same as

     for n in 0..3 {
         println!("{}", n);
     }
    
  • Rust .. excludes the last value, like C. Use ..= to include it.

  • A whole pile of methods exist for working with iterators, for example

     println!("{}", (1..5).sum());
    

    Many methods make a new iterator from an old, for example

     for i in (0..5).rev() {
         println!("{}", i);
     }
    
  • Iterators enable a "functional" style of programming; chain them together to produce a desired value instead of writing explicit loops

Closures

  • Anonymous functions ("lambdas") that can reference local variables

    // Squaring function.
    |n| n * n
    
  • Unlike fn, type inference is attempted on closure arguments and result

  • Type is almost "first-class": values can be stored in variables, passed around, etc

  • Normally use with methods that want to do a computation as part of their action

    let g2 = (1..5).map(|n| n * n).sum();
    
Last modified: Tuesday, 6 April 2021, 2:30 AM