面试题答案
一键面试fn call_length_closure<F>(closure: F)
where
F: Fn(&str) -> usize,
{
let s = String::from("hello");
let len = closure(&s);
println!("Length of the string is: {}", len);
}
闭包捕获变量的三种方式
- 按值捕获(
move
语义):使用move
关键字,闭包会获取变量的所有权,将变量从定义处移动到闭包内部。这种方式适用于闭包需要在不同的作用域中使用变量,并且变量在闭包外部不再需要的场景。 - 按不可变借用捕获:闭包可以不可变地借用其环境中的变量,当闭包只需要读取变量的值时使用这种方式。在我们的例子中,闭包接受
&str
作为参数,并没有修改字符串,所以使用这种方式捕获字符串切片。 - 按可变借用捕获:闭包可以可变地借用其环境中的变量,允许在闭包内部修改变量的值。当闭包需要修改捕获的变量时使用这种方式。
在这个场景下的选择原因
在这个场景中,闭包接受一个字符串切片&str
作为参数,并且只需要返回切片的长度,即仅读取数据而不修改。因此选择按不可变借用捕获的方式,这样既满足闭包读取数据的需求,又避免了不必要的所有权转移,同时防止了悬垂指针或内存泄漏的问题。闭包参数&str
指向的字符串切片的所有权仍在调用闭包的函数内(如上述代码中的let s = String::from("hello");
,s
的所有权在call_length_closure
函数内),在函数结束时会正常释放内存。