fnmain() { // Increment via closures and functions. fnfunction(i: i32) -> i32 { i + 1 }
// Closures are anonymous, here we are binding them to references // Annotation is identical to function annotation but is optional // as are the `{}` wrapping the body. These nameless functions // are assigned to appropriately named variables. let closure_annotated = |i: i32| -> i32 { i + 1 }; let closure_inferred = |i| i + 1;
let i = 1; // Call the function and closures. println!("function: {}", function(i)); println!("closure_annotated: {}", closure_annotated(i)); println!("closure_inferred: {}", closure_inferred(i));
// A closure taking no arguments which returns an `i32`. // The return type is inferred(推断的). let one = || 1; println!("closure returning one: {}", one()); }
// A closure to print `color` which immediately borrows (`&`) // `color` and stores the borrow and closure in the `print` // variable. It will remain borrowed until `print` goes out of // scope. `println!` only requires `by reference` so it doesn't // impose anything more restrictive. let print = || println!("`color`: {}", color);
// Call the closure using the borrow. print(); print();
letmut count = 0;
// A closure to increment `count` could take either `&mut count` // or `count` but `&mut count` is less restrictive so it takes // that. Immediately borrows `count`. // // A `mut` is required on `inc` because a `&mut` is stored inside. // Thus, calling the closure mutates the closure which requires // a `mut`. letmut inc = || { count += 1; println!("`count`: {}", count); };
// Call the closure. inc(); inc(); // count = 10; error[E0506]: cannot assign to `count` because it is borrowed // println!("return count and change {}", count);
// `mem::drop` requires `T` so this must take by value. A copy type // would copy into the closure leaving the original untouched. // A non-copy must move and so `movable` immediately moves into // the closure. let consume = || { println!("`movable`: {:?}", movable); mem::drop(movable); };
// `consume` consumes the variable so this can only be called once. consume(); //consume(); // ^ TODO: Try uncommenting this line. }
1 2 3 4 5
`color`: green `color`: green `count`: 1 `count`: 2 `movable`: 3