基本概念
闭包就是匿名函数或者lambda表达式,由于rust的一些特殊语法,rust中的闭包与其他语言有些不一样的用法,每次看过很容易忘记,特此记录。
基本语法
闭包的基本定义方法是:
- 使用 || 替代 () 将输入变量括起来。
- 区块定界符{}将所有函数中的表达式扩起来,如果只有一条表达式也可以不加。
- 闭包与函数的一大区别是,闭包能够在内部使用上层定义的外部变量。
基本例子:
let closure_annotated = |i: i32| -> i32 { i + 1 };
let i = 3;
println!("closure_annotated: {}", closure_annotated(i));
//输出 closure_annotated:4
引用捕获:
let color = "green";
//此处的闭包会捕获了 '&T'
let print = || println!("`color`: {}", color);
// 使用借用来调用闭包。
print();
print();
可变引用捕获(捕获并改变变量):
let mut count = 0;
//此处的闭包会捕获了 '&mut T'
//因为counti在闭包中被改变了, 所以必须使用mut来修饰, 否则编译器报错
let mut inc = || {
count += 1;
println!("`count`: {}", count);
};
inc();
inc();
值捕获并释放变量:
//movable是不可复制类型
let movable = Box::new(3);
//此处的闭包会捕获 'T'
let consume = || {
println!("`movable`: {:?}", movable);
mem::drop(movable);
};
//该闭包只能调用一次, 否则编译器报错
consume();
闭包作为输入变量
闭包的类型
按照对于捕获变量的不同处理闭包可以分为三种类型: Fn, Fnmut, FnOnce
分别对应了的捕获方式是引用捕获’&T’, 可变引用捕获’&mut T’, 值捕获’T’。
其使用的受限程度依次递减,意思是说FnOnce可以通过三种方式捕获变量,编译器会根据闭包内的变量处理方式判断应该使用哪种捕获方式。
// To do