[−][src]Function tao_of_rust::ch06::closures::pass_closure
pub fn pass_closure()
闭包作为参数或返回值传递
Base usage: 闭包作为参数
fn boxed_closure(c: &mut Vec<Box<Fn()>>){ let s = "second"; c.push(Box::new(|| println!("first"))); c.push(Box::new(move || println!("{}", s))); c.push(Box::new(|| println!("third"))); } fn main(){ let mut c: Vec<Box<Fn()>> = vec![]; boxed_closure(&mut c); for f in c { f(); // first / second / third } }Run
Base usage: 实现any方法,静态分发
注意:此处自定义Any,不同于标准库提供的Any
use std::ops::Fn; trait Any { fn any<F>(&self, f: F) -> bool where Self: Sized, F: Fn(u32) -> bool; } impl Any for Vec<u32> { fn any<F>(&self, f: F) -> bool where Self: Sized, F: Fn(u32) -> bool { for &x in self { if f(x) { return true; } } false } } fn main(){ let v = vec![1,2,3]; let b = v.any(|x| x == 3); println!("{:?}", b); }Run
Base usage: 函数指针也实现了Fn/FnMut/FnOnce
fn call<F>(closure: F) -> i32 where F: Fn(i32) -> i32 { closure(1) } fn counter(i: i32) -> i32 { i+1 } fn main(){ let result = call(counter); assert_eq!(2, result); }Run
Base usage: 实现any方法,动态分发
注意:此处自定义Any,不同于标准库提供的Any
trait Any { fn any(&self, f: &(Fn(u32) -> bool)) -> bool; } impl Any for Vec<u32> { fn any(&self, f: &(Fn(u32) -> bool)) -> bool { for &x in self.iter() { if f(x) { return true; } } false } } fn main(){ let v = vec![1,2,3]; let b = v.any(&|x| x == 3); println!("{:?}", b); }Run
Base usage: 只有逃逸闭包可装箱
fn main(){ let s = "hello"; let c: Box<Fn() + 'static> = Box::new( move||{ s;}); }Run
Base usage: 闭包作为返回值
fn square() -> Box<Fn(i32) -> i32> { Box::new(|i| i*i ) } fn main(){ let square = square(); assert_eq!(4, square(2)); assert_eq!(9, square(3)); }Run
Base usage: 闭包作为返回值 报错
fn square() -> Box<FnOnce(i32) -> i32> { Box::new( |i| {i*i }) } fn main(){ let square = square(); assert_eq!(4, square(2)); }Run
Base usage: 使用FnBox修正
#![feature(fnbox)] use std::boxed::FnBox; fn square() -> Box<FnBox(i32) -> i32> { Box::new( |i| {i*i }) } fn main(){ let square = square(); assert_eq!(4, square(2)); }Run
Base usage: 使用impl Trait
fn square() -> impl FnOnce(i32) -> i32 { |i| {i*i } } fn main(){ let square = square(); assert_eq!(4, square(2)); }Run