我试图实施一个简单的建设者,但却终身难忘。以下是error: borrowed value does not live long enough
。 This question似乎很相似。如果我将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);
}
答案 0 :(得分:10)
问题是,您使用来自Type
的{{1}}创建了一个包含字符串切片的String
,但使用TypeBuilder
创建的TypeBuilder
实例是在相同的new()
语句中立即销毁,因此如果允许,则字符串切片将变为悬空。这就是为什么它首先将let
存储在变量中的原因。
您对构建器的方法存在的问题是构建器是其构建的值的数据所有者:TypeBuilder
引用Type
的内容。这意味着TypeBuilder
个实例始终与Type
个实例相关联,您无法创建TypeBuilder
并删除Type
。然而,这实际上并不自然 - 建造者通常是临时物体,只有在施工期间才需要。
因此,为了使构建器模式正常工作,您的TypeBuilder
必须成为数据的所有者:
Type
然后构建器应按值传递,然后由struct Type {
s: String,
}
消耗:
finalize()
这样您的构建代码应该完全正常工作。