Rust 如何避免向辅助方法重复传递 &str,又不引入生命周期参数?
数据小陈
可以在 f 中定义一个局部闭包,捕获 self 和 val。调用闭包时就不用重复传入 val,也不需要给 MyStruct 添加生命周期参数。
用局部闭包绑定参数
原示例中的三次 self.b(val) 都使用同一个字符串切片,而 b 只通过 &self 访问结构体。可以保留辅助方法,用闭包处理重复传参:
struct MyStruct;
impl MyStruct {
fn b(&self, val: &str) {
println!("complicated string processing {}", val);
}
fn f(&self, val: &str) {
let b = || self.b(val);
b();
b();
b();
}
}
b 是局部闭包变量,self.b 仍然指向原来的方法。闭包通过借用捕获所需的值,编译器会推断相关生命周期,无需手写生命周期参数,也不会复制字符串内容。
如果这段处理逻辑只在 f 中使用,也可以直接放进闭包:
fn f(&self, val: &str) {
let b = || {
println!("complicated string processing {}", val);
};
b();
b();
b();
}
如果其他方法也要调用这个辅助方法,保留第一种写法更方便复用。
为什么不需要给结构体添加生命周期参数?
fn f(&self, val: &str) 使用了生命周期省略规则。引用仍然受生命周期约束,只是不需要显式写出。
局部闭包在 f 内使用,借用关系由编译器检查。由于 val 没有存入 MyStruct,结构体定义也不需要增加生命周期参数。
如果结构体要保存对外部字符串的借用,就需要标注生命周期:
struct MyStruct<'a> {
val: &'a str,
}
这里必须表达结构体与被借用字符串之间的有效期关系,不能仅靠省略标注消除这个约束。
什么时候应该使用 String 字段?
如果字符串确实属于对象的长期状态,可以让结构体持有 String:
struct MyStruct {
val: String,
}
impl MyStruct {
fn b(&self) {
println!("complicated string processing {}", self.val);
}
fn f(&self) {
self.b();
self.b();
self.b();
}
}
这样字符串就归结构体所有。从借用的 &str 创建 String 时,通常需要分配内存并复制内容。原问题只需要在一次 f 调用期间复用 val,用局部闭包就足够了。
备注:内容仅供参考。
