生成器模式 - 借来的价值不够长

时间:2015-04-06 09:04:56

标签: rust

我试图实施一个简单的建设者,但却终身难忘。以下是error: borrowed value does not live long enoughThis 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);
}

1 个答案:

答案 0 :(得分:10)

问题是,您使用来自Type的{​​{1}}创建了一个包含字符串切片的String,但使用TypeBuilder创建的TypeBuilder实例是在相同的new()语句中立即销毁,因此如果允许,则字符串切片将变为悬空。这就是为什么它首先将let存储在变量中的原因。

您对构建器的方法存在的问题是构建器是其构建的值的数据所有者:TypeBuilder引用Type的内容。这意味着TypeBuilder个实例始终与Type个实例相关联,您无法创建TypeBuilder并删除Type。然而,这实际上并不自然 - 建造者通常是临时物体,只有在施工期间才需要。

因此,为了使构建器模式正常工作,您的TypeBuilder必须成为数据的所有者:

Type

然后构建器应按值传递,然后由struct Type { s: String, } 消耗:

finalize()

这样您的构建代码应该完全正常工作。