繁体   English   中英

数组寿命不足

[英]`array` doesn't live long enough

我想保留一个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> {
   |                                            ^

在您发布的MCVE中,struct 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包括Holded 那是解决这个问题的一种方法。 但是我不确定这是否适用于您的原始问题。

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() )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM