面试题答案
一键面试在Rust中,当闭包捕获外部变量且涉及链式调用时,通过明确的生命周期标注可以确保内存安全。以下是一个示例及解释:
// 定义一个结构体
struct MyStruct<'a> {
data: &'a str,
}
fn main() {
let s = String::from("hello");
let my_struct = MyStruct { data: &s };
// 定义闭包,捕获my_struct
let closure1 = move |input: &str| {
println!("closure1: {}", input);
my_struct.data
};
// 链式调用闭包
let result = closure1(&s).to_string();
println!("result: {}", result);
}
生命周期标注及解释
- 结构体的生命周期标注:
struct MyStruct<'a> { data: &'a str, }
,这里的'a
表示data
引用的生命周期,它必须与结构体实例的生命周期相同。 - 闭包捕获:
let closure1 = move |input: &str| { ... }
,使用move
关键字将my_struct
的所有权转移到闭包中。这确保了闭包对my_struct
的使用不会导致悬空指针,因为闭包现在拥有my_struct
。 - 链式调用:
let result = closure1(&s).to_string();
,在链式调用中,闭包closure1
接受一个&str
类型的参数,并返回my_struct.data
,它也是&str
类型。由于闭包已经拥有my_struct
,所以不会出现生命周期问题。
通过move
关键字和明确的生命周期标注,Rust编译器能够在编译时检查并确保在闭包链式调用过程中不会出现悬空指针或内存泄漏等问题。