面试题答案
一键面试fn main() {
let greeting = "Hello";
let name = "World";
let closure = || format!("{}, {}", greeting, name);
println!("{}", closure());
}
闭包捕获变量的方式
在上述代码中,闭包 || format!("{}, {}", greeting, name)
捕获了外部变量 greeting
和 name
。Rust闭包捕获变量有三种方式,分别对应 Fn
特质家族中的不同特质:
- 按值捕获(
FnOnce
):闭包获取变量的所有权,只能调用一次。 - 按可变引用捕获(
FnMut
):闭包获取变量的可变引用,可以多次调用并修改变量。 - 按不可变引用捕获(
Fn
):闭包获取变量的不可变引用,可以多次调用,但不能修改变量。
在这个例子中,闭包按不可变引用捕获了 greeting
和 name
,因为 format!
宏只需要对它们的不可变访问,所以闭包实现了 Fn
特质。
生命周期处理
闭包捕获的变量的生命周期与闭包本身的生命周期相关。在这个例子中,greeting
和 name
是字符串字面量,它们的生命周期是 'static
。闭包捕获了这些变量的不可变引用,这些引用的生命周期被闭包的调用者所约束。因为闭包在 main
函数内定义和调用,所以闭包的生命周期与 main
函数的生命周期一致,直到 main
函数结束,闭包及其捕获的引用才会失效。由于 greeting
和 name
的生命周期是 'static
,它们的生命周期长于闭包的生命周期,因此不存在生命周期不匹配的问题。