Home
# Les closures --- ## Les fonctions anonymes Les fonctions standards ```rust fn foo(x: f32,y: f32) -> f32 { (x * y) / (x + y) } ``` Les fonctions anonymes ```rust fn main() { let a = |x: f32, y: f32| -> f32 { (x * y) / (x + y) }; let b = |x: f32, y: f32| (x * y) / (x + y); } ``` --- ## Les fonctions d'ordre supérieur Fonction qui prend une fonction en argument ```rust fn foo(f: fn (i32) -> i32) -> i32 { f(5) } ``` Fonction qui retourne une fonction ```rust fn bar() -> fn (i32) -> i32 { |x| x+1 } ``` --- ## Closures Capture de la variable `a` dans l'environnement de `b` ```rust fn main() { let a: Option
= Some(12); let b = |x: bool| x ^ a.is_some(); println!("{}", b(true)); } ``` --- ## Le trait Fn 1/3 Problème ? ```rust compile_fail fn foo(f:fn (i32) -> i32) -> i32 { f(5) } fn main() { let a: Option
= Some(12); let b = |x: i32| x + a.unwrap(); println!("{}", foo(b)); } ``` --- ## Le trait Fn 2/3 ```console Compiling playground v0.0.1 (/playground) error[E0308]: mismatched types --> src/main.rs:7:24 | 6 | let b = |x:i32| x + a.unwrap(); | ------- the found closure 7 | println!("{}", foo(b)); | --- ^ expected fn pointer, found closure | | | arguments to this function are incorrect | = note: expected fn pointer `fn(i32) -> i32` found closure `[closure@src/main.rs:6:13: 6:20]` note: closures can only be coerced to `fn` types if they do not capture any variables --> src/main.rs:6:25 | 6 | let b = |x:i32| x + a.unwrap(); | ^ `a` captured here note: function defined here --> src/main.rs:1:4 | 1 | fn foo(f:fn (i32) -> i32) -> i32 { | ^^^ ----------------- For more information about this error, try `rustc --explain E0308`. ``` --- ## Le trait Fn 3/3 ```rust fn foo
i32>(f: F) -> i32 { f(5) } fn main() { let a: Option
= Some(12); let b = |x:i32| x + a.unwrap(); println!("{}", foo(b)); } ``` --- ## Exemple avec les options 1/2 La fonction map ```rust fn main() { let a: Option
= Some(12); println!("{}", a.map(|x| x * 2).unwrap()); let b: Option
= None; println!("{}", b.map(|x| x * 2).is_some()); } ``` --- ## Exemple avec les options 2/2 La fonction filter ```rust fn main() { let a: Option
= Some(12); println!("{}", a.filter(|x| x % 6 == 1).is_none()); let b: Option
= None; println!("{}", b.filter(|x| x % 6 == 0).is_some()); } ```