建造者模式——借来的价值活得不够久 [英] Builder pattern - borrowed value does not live long enough
问题描述
我正在尝试实现一个简单的构建器,但在生命周期中挣扎.以下给出了错误:借来的价值寿命不够长
.这个问题似乎很相似.如果我将 t
存储在一个可变变量中,然后调用 s
并完成它的工作,但我想让一个班轮工作.我究竟做错了什么?
I'm trying to implement a simple builder but struggling with lifetimes. The following is giving error: borrowed value does not live long enough
. This question seems similar. If I store t
in a mutable variable and then call s
and finalize it works, but I want to get the one liner to work. What am I doing wrong?
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);
}
推荐答案
问题是您正在使用基于 String
的字符串切片创建 Type
code>TypeBuilder,但是用 new()
创建的 TypeBuilder
实例会在同一个 let
语句中立即销毁,所以如果这是如果允许,字符串切片将变得悬空.这就是为什么当您首先将 TypeBuilder
存储在变量中时它会起作用的原因.
The problem is that you're creating Type
with a string slice based on a String
from TypeBuilder
, but TypeBuilder
instance created with new()
is destroyed immediately in the same let
statement, so if this was allowed, the string slice would became dangling. And that's why it works when you store TypeBuilder
in a variable first.
您对构建器的方法的问题在于,构建器是它构建的值的数据的所有者:Type
引用了 TypeBuilder
的内容.这意味着 Type
实例总是绑定到 TypeBuilder
实例,并且你不能创建 Type
并删除 TypeBuilder
.然而,这真的很不自然 - 构建器通常是临时对象,仅在构建期间才需要.
The problem with your approach to the builder is that the builder is the owner of data for the value it builds: Type
references the contents of TypeBuilder
. This means that Type
instances are always tied to TypeBuilder
instances, and you just cannot create Type
and drop TypeBuilder
. However, this is really unnatural - builders are usually transient objects which are only necessary during construction.
因此,为了使构建器模式正常工作,您的 Type
必须成为数据的所有者:
Consequently, in order for the builder pattern to work correctly your Type
must become the owner of the data:
struct Type {
s: String,
}
那么builder应该通过值传递,然后被finalize()
消耗:
Then the builder should be passed by value and then consumed by 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 }
}
}
这样您的构建代码就应该完全按照原样工作.
This way your building code should work exactly as it is.
这篇关于建造者模式——借来的价值活得不够久的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!