可变元素在结构体中的生命周期

4
如何在一个结构体中定义可变元素?如果我有以下示例:
struct User<'a> {
    reference: String,
    email: String,
    addresses: &'a mut Vec<Address>
}

struct Address {
    street: String,
    city: String
}

fn main() {

    let mut users = Vec::new();
    users.push(User {
        reference: "ref".to_string(),
        email: "test@test.com".to_string(),
        addresses: &mut Vec::new()
    });

}

...它会产生一个错误:

src/main.rs:18:19: 18:29 error: borrowed value does not live long enough
src/main.rs:18      addresses: &mut Vec::new()
                                    ^~~~~~~~~~
src/main.rs:14:29: 21:2 note: reference must be valid for the block suffix following statement 0 at 14:28...
src/main.rs:14  let mut users = Vec::new();
src/main.rs:15  users.push(User {
src/main.rs:16      reference: "ref".to_string(),
src/main.rs:17      email: "test@test.com".to_string(),
src/main.rs:18      addresses: &mut Vec::new()
src/main.rs:19  });
               ...
src/main.rs:15:2: 19:5 note: ...but borrowed value is only valid for the statement at 15:1
src/main.rs:15  users.push(User {
src/main.rs:16      reference: "ref".to_string(),
src/main.rs:17      email: "test@test.com".to_string(),
src/main.rs:18      addresses: &mut Vec::new()
src/main.rs:19  });
src/main.rs:15:2: 19:5 help: consider using a `let` binding to increase its lifetime
src/main.rs:15  users.push(User {
src/main.rs:16      reference: "ref".to_string(),
src/main.rs:17      email: "test@test.com".to_string(),
src/main.rs:18      addresses: &mut Vec::new()
src/main.rs:19  });
error: aborting due to previous error

如果我采纳编译器的建议 help: consider using a let binding to increase its lifetime

...并考虑使用let绑定来增加其生命周期:

fn main() {

    let mut users = Vec::new();
    let mut addresses = Vec::new();
    users.push(User {
        reference: "ref".to_string(),
        email: "test@test.com".to_string(),
        addresses: &mut addresses
    });

}

我仍然遇到了类似的错误:

...

src/main.rs:19:19: 19:28 error: `addresses` does not live long enough
src/main.rs:19      addresses: &mut addresses
                                    ^~~~~~~~~
src/main.rs:14:29: 22:2 note: reference must be valid for the block suffix following statement 0 at 14:28...
src/main.rs:14  let mut users = Vec::new();
src/main.rs:15  let mut addresses = Vec::new();
src/main.rs:16  users.push(User {
src/main.rs:17      reference: "ref".to_string(),
src/main.rs:18      email: "test@test.com".to_string(),
src/main.rs:19      addresses: &mut addresses
               ...
src/main.rs:15:33: 22:2 note: ...but borrowed value is only valid for the block suffix following statement 1 at 15:32
src/main.rs:15  let mut addresses = Vec::new();
src/main.rs:16  users.push(User {
src/main.rs:17      reference: "ref".to_string(),
src/main.rs:18      email: "test@test.com".to_string(),
src/main.rs:19      addresses: &mut addresses
src/main.rs:20  });
               ...
error: aborting due to previous error

这里有什么问题?

更新: 所以这个情况实际上更接近于我的问题:

struct User<'a> {
    reference: String,
    email: String,
    addresses: &'a mut Vec<Address>
}

struct Address {
    street: String,
    city: String
}

fn main() {

    let mut users = get_users();

}

fn get_users<'a>() -> Vec<User<'a>> {

    let mut addresses = Vec::new();
    let mut users = Vec::new();
    users.push(User {
        reference: "ref".to_string(),
        email: "test@test.com".to_string(),
        addresses: &mut addresses
    });

    users

}

...并且它引起了这个错误:

src/main.rs:26:25: 26:34 error: `addresses` does not live long enough
src/main.rs:26         addresses: &mut addresses
                                       ^~~~~~~~~
src/main.rs:19:37: 31:2 note: reference must be valid for the lifetime 'a as defined on the block at 19:36...
src/main.rs:19 fn get_users<'a>() -> Vec<User<'a>> {
src/main.rs:20 
src/main.rs:21  let mut addresses = Vec::new();
src/main.rs:22     let mut users = Vec::new();
src/main.rs:23     users.push(User {
src/main.rs:24         reference: "ref".to_string(),
               ...
src/main.rs:21:33: 31:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 21:32
src/main.rs:21  let mut addresses = Vec::new();
src/main.rs:22     let mut users = Vec::new();
src/main.rs:23     users.push(User {
src/main.rs:24         reference: "ref".to_string(),
src/main.rs:25         email: "test@test.com".to_string(),
src/main.rs:26         addresses: &mut addresses
               ...
error: aborting due to previous error

1
你的问题与可变性无关。在发布问题之前,请尽力将问题简化为MCVE。我知道这可能很困难,但我保证它会帮助你更好地理解问题,并获得更快的答案 ^_^。 - Shepmaster
2
阅读答案,你将来会需要这些知识,但对于这个特定的例子,你可能不想要一个&mut Vec。只需在User中存储一个Vec即可。用户对象不借用和修改其他人的地址列表,每个用户都有自己的地址列表并拥有它。 - user395760
@Caballero 不用担心完全理解不了,只要你尝试过就好了 ^_^。我使用了你的示例代码并重新排列了语句,它可以工作。或者你是指你的示例不在问题中? - Shepmaster
@Caballero 或许吧!我期待着你的下一个问题!^_^ - Shepmaster
2
它不是这样工作的。所有这些问题的根源都来自于所有权和借用的基本概念,而所有这些问题(包括你的问题)只是它们的不同应用。在这里,您正在尝试从函数返回对所拥有结构(Vec<Address>)的借用引用,但是该拥有结构由函数的堆栈帧拥有,当此函数返回时,该结构将被销毁,并且如果允许返回,则返回的引用将变为悬空引用。这与其他问题本质上是相同的。 - Vladimir Matveev
显示剩余7条评论
1个回答

7

我知道这个问题以前已经有人回答过了,但是我找不到它...如果你找到了,请随意将其标记为重复。

问题在于您正在尝试将引用存储在一个容器中,而该容器将超出引用的生命周期。以下是您问题的MCVE

fn main() {
    let mut things = vec![];
    let a = 42;
    things.push(&a);
}

创建的顺序与删除的顺序相反,因此a会在things之前被删除。然而,things引用了a,这意味着会出现悬空引用的情况,而Rust不允许这种情况。请重新排列语句。

fn main() {
    let a = 42;
    let mut things = vec![];
    things.push(&a);
}

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