建造者模式——借来的价值活得不够长
Builder pattern - borrowed value does not live long enough
我正在尝试实现一个简单的构建器,但遇到了生命周期问题。下面给出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);
}
问题是您正在使用基于 TypeBuilder
的 String
的字符串切片创建 Type
,但是 TypeBuilder
使用 [=16= 创建的实例] 在同一个 let
语句中立即销毁,因此如果允许这样做,字符串切片将变得悬空。这就是当您首先将 TypeBuilder
存储在变量中时它起作用的原因。
您对构建器的处理方法存在问题,构建器是其构建值的数据所有者:Type
引用了 TypeBuilder
的内容。这意味着 Type
个实例总是与 TypeBuilder
个实例相关联,并且您不能创建 Type
和删除 TypeBuilder
。然而,这真的很不自然 - 构建器通常是临时对象,仅在构建期间才需要。
因此,为了使构建器模式正常工作,您的 Type
必须成为数据的所有者:
struct Type {
s: String,
}
那么构建器应该是按值传递,然后被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 }
}
}
这样您的建筑规范应该完全按照原样工作。
我正在尝试实现一个简单的构建器,但遇到了生命周期问题。下面给出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);
}
问题是您正在使用基于 TypeBuilder
的 String
的字符串切片创建 Type
,但是 TypeBuilder
使用 [=16= 创建的实例] 在同一个 let
语句中立即销毁,因此如果允许这样做,字符串切片将变得悬空。这就是当您首先将 TypeBuilder
存储在变量中时它起作用的原因。
您对构建器的处理方法存在问题,构建器是其构建值的数据所有者:Type
引用了 TypeBuilder
的内容。这意味着 Type
个实例总是与 TypeBuilder
个实例相关联,并且您不能创建 Type
和删除 TypeBuilder
。然而,这真的很不自然 - 构建器通常是临时对象,仅在构建期间才需要。
因此,为了使构建器模式正常工作,您的 Type
必须成为数据的所有者:
struct Type {
s: String,
}
那么构建器应该是按值传递,然后被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 }
}
}
这样您的建筑规范应该完全按照原样工作。