let add_one = | num | {
	num + 1
};

由于闭包和当前上下文相关联,所以 Rust 可以进行类型推导,类型注解也就不是必要的,但是依然可以自己添加:

let add_one = | num: i32 | {
	num + 1
};

fn  add_one_v1   (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x|             { x + 1 };
let add_one_v4 = |x|               x + 1  ;

使用 Fn 存储闭包类型

struct Cacher<T>
	where T: Fn(u32) -> u32
{
	calculation: T,
	value: Option<u32>,
}

impl Cacher<T>
	where T: Fn(u32) -> u32
{
	fn new(calculation: T) -> Cacher<T> {
		Cacher {
			calculation,
			value: None,
		}
	}

	fn value(&mut self, arg: u32) -> u32 {
		if let Some(value) = self.value {
				value
		} else {
				let value = (self.calculation)(arg);
				self.value = Some(value);
				value
		}
	}
}

闭包和函数的区别:闭包会捕捉当前环境,但是函数不会。

三种不同 Fn trait

  • FnOnce 定义时获取引用环境的变量的所有权,并只能调用一次(不能多次获得环境变量的所有权)
  • Fn 立即从所在环境借用值
  • FnMut 可以改变引用环境的引用值

如果想要强制取得使用的所在环境变量的所有权,可以使用 move 关键字

fn main() {
	let x = vec![1, 2, 3];
	let euqal_to_x = move |z| z == x;

	// x has move to closure, so can't use it anymore.
}