建造者模式——借来的价值活得不够长

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);
}

问题是您正在使用基于 TypeBuilderString 的字符串切片创建 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 }
    }
}

这样您的建筑规范应该完全按照原样工作。