返回一个包含可变值的结构体

8
我有下面这段代码,我试图返回一个带有字段 values 默认值的结构体 Foo。这些值可能会在以后更改。但编译器报错:
error: `initial` does not live long enough

这怎么能够实现呢?还有其他替代方案吗?
struct Foo <'a> {
    values: &'a mut Vec<i32>,
}

impl <'a> Foo <'a> {
    fn new() -> Foo <'a> {
        let initial = vec![1, 2];

        Foo { values: &mut initial }
    }
}

let my_foo = Foo::new();

my_foo.values.push(3);
1个回答

18

这里有两个问题。

第一个问题是你不需要使用&mut来使结构体字段可变。在Rust中,可变性是继承的。也就是说,如果你有一个存储在可变变量(let mut f: Foo)中的Foo,它的字段是可变的;如果它在不可变变量(let f: Foo)中,它的字段是不可变的。解决方案就是使用:

struct Foo {
    values: Vec<i32>,
}

并且通过值返回Foo

第二个问题(也是实际编译错误的根源)是你试图返回对函数内部创建的某些东西的引用。这是不可能的。不,没有任何方法可以绕过它;你不能以某种方式延长initial的生命周期,返回initial和借用将不起作用。真的。这是Rust专门设计的绝对禁止之一。

如果你想要从一个函数中转移出某些东西,则必须满足以下两个条件之一:

  1. 它被存储在函数外的某个地方,并且将超出当前调用的生命周期(例如,你作为参数获得了借用;返回不算),或者

  2. 你正在返回所有权,而不仅仅是一个借用的引用。

修正后的Foo之所以有效,是因为它拥有Vec<i32>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接