【问题标题】:`array` doesn't live long enough`array` 的寿命不够长
【发布时间】:2017-01-27 23:30:10
【问题描述】:

我想保留一个Holded 实例,但我不能,因为它在一个数组中。如何从数组中“提取”此实例并将其保存在 Object 实例中? (在我的原始代码中,我没有数组而是迭代器)。这是等效的代码:

struct Holded {
    value: u8,
}

struct Holder;

impl Holder {
    pub fn get(&self) -> [Holded; 2] {
        [Holded { value: 0 }, Holded { value: 1 }]
    }
}

struct Object<'a> {
    holded: &'a Holded,
}

fn main() {
    let holder = Holder;

    let obj = work(&holder).unwrap();
    println!("{}", obj.holded.value);
}

fn work(holder: &Holder) -> Option<Object> {
    let mut obj: Object;
    let array = holder.get();

    for h in array.into_iter() {
        if h.value == 1u8 {
            obj = Object { holded: h };
            return Some(obj);
        }
    }

    None
}

错误信息:

error: `array` does not live long enough
  --> src/main.rs:28:14
   |
28 |     for h in array.into_iter() {
   |              ^^^^^ does not live long enough
...
36 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the anonymous lifetime #1 defined on the block at 24:43...
  --> src/main.rs:24:44
   |
24 | fn work(holder: &Holder) -> Option<Object> {
   |                                            ^

【问题讨论】:

  • 87 questions with the same error message。或许您可以花时间回顾一下其中的一些问题,并解释为什么这个问题很特别、不同且尚未得到解答?
  • 我已经看过很多了,但这里的问题主要是我不太明白为什么我有这个错误,看到其他帖子对我没有帮助关于这个。
  • 我也看过很多,问题在一篇中说明。 — 如果您不指出现有问题中的 any 有什么错误,看看它有多大用处?如果您不告诉我们出了什么问题,我们只会重复您已经不理解的相同答案,您不会得到帮助,更糟糕的是,还会有一个下一个人不会的答案阅读并忽略并要求修复他们的代码。
  • 我编译了您的代码并将整个错误消息放入问题中。你读过编译器说的吗?你试过了吗?
  • 另外,我强烈建议您学习创建minimal reproducible example。这样做会帮助你学习和成长为一名程序员。它也很有帮助,因为您可以专注于手头的问题,而不会被任何额外的垃圾分散注意力。这是one example of how to reduce your code while maintaining the same error message。这可能是stackoverflow.com/q/32300132/155423 的副本。

标签: rust


【解决方案1】:

在您发布的 MCVE 中,结构 Object 包含对 Holded 的引用:

struct Object<'a> {
    holded: &'a Holded,
}

在函数work() 中,您返回一个Object(可选):

fn work(holder: &Holder) -> Option<Object> {

你从一个按值返回的函数中获取Holded

impl Holder {
    pub fn get( &self ) -> [Holded; 2] {
        [Holded { value: 0 }, Holded { value: 1 }]
    }
}

现在这将永远行不通。如果您返回对Holded 的引用,那么您引用的Holded 必须存储在某处。这意味着要么作为输入,要么作为函数 work() 的输出。

我重写了您的示例,将Holded 包含在Holder 中。这是解决这个问题的一种方法。但我不确定这是否适用于您原来的问题。

struct Holded {
    value: u8,
}

struct Holder{
    value: [Holded; 2],
}

impl Holder {
    pub fn new() -> Holder {
        Holder {value: [Holded { value: 0 }, Holded { value: 1 }] } 
    }

    pub fn get( &self ) -> &[Holded; 2] {
        &self.value
    }
}

struct Object<'a> {
    holded: &'a Holded,
}

fn main() {
    let holder = Holder::new();

    let obj = work(&holder).unwrap();
    println!("{}", obj.holded.value);

    let obj = work2(&holder).unwrap();
    println!("{}", obj.holded.value);
}

fn work(holder: &Holder) -> Option<Object> {
    let obj: Object;
    let array = holder.get();

    for h in array.into_iter() {
        if h.value == 1u8 {
            obj = Object { holded: h };
            return Some(obj);
        }
    }

    None
}

fn work2(holder: &Holder) -> Option<Object> {
    holder.get()
        .iter()
        .filter(|h| h.value == 1u8)
        .map(|h| Object { holded: h })
        .next()
}

您注意到我还添加了一种不同的方式来实现 work() 函数 (work2())。

【讨论】:

    猜你喜欢
    • 2015-05-26
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 2017-03-09
    相关资源
    最近更新 更多