【问题标题】:Lifetime of a mutable element in struct结构中可变元素的生命周期
【发布时间】:2015-06-16 16:13:40
【问题描述】:

如何在struct 中定义可变元素?如果我有以下示例:

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:

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

【问题讨论】:

  • 您的问题与可变性无关。在发布之前,请努力将您的问题减少到MCVE。我知道这可能很困难,但我保证它将帮助您更好地理解问题并获得更快的答案^_^。
  • 阅读答案,您将来会需要这些知识,但对于这个特定示例,您可能不需要&amp;mut Vec。只需将Vec 存储在User 中。用户对象不会借用和修改别人的地址列表,每个人都有自己的地址列表并拥有它。
  • @Shepmaster 我尽可能地减少它。您的回答帮助我修复了简化的示例,不幸的是它不适用于我仍然产生相同错误的实际情况。希望我现在可以解决问题,因为我在正确的轨道上。谢谢。
  • @Caballero 不用担心没有得到它,只要你尝试过^_^。我使用了您的示例代码并重新排序了语句并且它起作用了。还是您的意思是您的示例不在问题中?
  • 这样不行。这整套问题源于一个来源,所有权和借款的基本概念,所有这些问题(包括您的问题)只是它们的不同应用。在这里,您尝试从函数返回对拥有结构 (Vec&lt;Address&gt;) 的借用引用,但该拥有结构由函数的堆栈框架拥有,当该函数返回时,该结构被销毁,并且如果允许返回它,返回的引用将变得悬空。这与其他问题基本相同。

标签: rust


【解决方案1】:

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

问题是您试图将引用存储在一个容器中,该引用的寿命将超过该引用。这是您的问题的MCVE

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

项目按照创建它们的相反顺序被删除,因此athings 之前被删除。然而,things 有一个对a 的引用,这意味着会有一个时间点有一个悬空引用,这是 Rust 不允许的。重新排列你的陈述:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-22
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    相关资源
    最近更新 更多