我正在努力实现一个简单的建设者,但却终身难忘.以下是给予error: borrowed value does not live long enough.这个问题似乎很相似.如果我存储t在一个可变变量然后调用s并最终确定它是有效的,但我想让一个衬里工作.我究竟做错了什么?
struct Type<'a> {
s: &'a String,
}
struct TypeBuilder {
s: String,
}
impl TypeBuilder {
fn new() -> TypeBuilder {
TypeBuilder { s: "".to_string() }
}
fn s(&mut self, s: String) -> &mut TypeBuilder {
self.s = s;
self
}
fn finalize(&self) -> Type {
Type { s: &self.s }
}
}
fn main() {
let t = TypeBuilder::new()
.s("a".to_string())
.finalize();
println!("string: {}", t.s);
}
Run Code Online (Sandbox Code Playgroud)
Vla*_*eev 10
问题是您正在Type使用基于Stringfrom 的字符串切片创建TypeBuilder,但是TypeBuilder创建的实例new()会立即在同一let语句中被销毁,因此如果允许,则字符串切片将变为悬空.这就是为什么它首先存储TypeBuilder在变量中的原因.
您对构建器的方法的问题在于构建器是它构建的值的数据的所有者:Type引用的内容TypeBuilder.这意味着Type实例总是与TypeBuilder实例绑定,而您无法创建Type和删除TypeBuilder.然而,这实际上是不自然的 - 建造者通常是临时物体,仅在施工期间是必需的.
因此,为了使构建器模式正常工作,您Type必须成为数据的所有者:
struct Type {
s: String,
}
Run Code Online (Sandbox Code Playgroud)
然后构建器应按值传递,然后通过finalize()以下方式使用:
impl TypeBuilder {
fn new() -> TypeBuilder {
TypeBuilder { s: "".to_string() }
}
fn s(mut self, s: String) -> TypeBuilder {
self.s = s;
self
}
fn finalize(self) -> Type {
Type { s: self.s }
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您的构建代码应该完全正常工作.