面试题答案
一键面试在Rust中,闭包捕获环境变量有三种方式:
- 按值捕获(
Copy
语义):- 底层实现特点:当闭包捕获的变量实现了
Copy
trait 时,会按值捕获。在这种情况下,闭包会直接复制这些变量的值到闭包实例内部。这意味着原始变量在闭包创建后仍然可以被正常使用,因为它的所有权没有被转移。例如,基本类型(如i32
、f64
)和实现了Copy
的结构体通常会按值捕获。
- 底层实现特点:当闭包捕获的变量实现了
let num = 5;
let closure = || println!("The number is: {}", num);
closure();
println!("num is still available: {}", num);
- 按值捕获(
Move
语义):- 底层实现特点:当闭包捕获的变量没有实现
Copy
trait 时,会按Move
语义捕获。此时,变量的所有权会被转移到闭包中,原始变量在闭包创建后就不能再被使用。例如,String
类型没有实现Copy
,当被闭包捕获时会转移所有权。
- 底层实现特点:当闭包捕获的变量没有实现
let s = String::from("hello");
let closure = move || println!("The string is: {}", s);
closure();
// println!("s is not available here: {}", s); // 这行会编译错误
- 按引用捕获:
- 底层实现特点:闭包可以通过引用捕获环境变量,这样不会转移变量的所有权,也不会复制变量的值。闭包会持有对原始变量的引用,这要求原始变量的生命周期至少要和闭包一样长。当闭包多次调用时,每次访问的都是同一个变量。
let mut num = 5;
let closure = || {
num += 1;
println!("The number is: {}", num);
};
closure();
println!("num is updated: {}", num);
按引用捕获的闭包类型签名中会体现引用类型,如Fn(&T)
或 Fn(&mut T)
,分别对应不可变引用和可变引用。