Rust:“.. 活得不够长”

Rust: ".. does not live long enough"

代码如下(有 Rust 初学者难度):

use std::cell::RefCell;
use std::collections::HashMap;

pub trait TIndex<'a> {
    // cut
}

pub struct HashMapIndex<'a> {
    pub filter_by_keyword: HashMap<String, &'a str> // simplified (and ugly)
}

impl<'a> TIndex<'a> for HashMapIndex<'a> {
    // cut
}

pub struct Matcher<'a> {
    pub index: &'a RefCell<Box<dyn TIndex<'a> + 'a>>
}

impl<'a> Matcher<'a> {
    pub fn new(index: &'a RefCell<Box<dyn TIndex<'a> + 'a>>) -> Self {
        Matcher {
            index
        }
    }
}

pub fn main() {
    let index = HashMapIndex {
        filter_by_keyword: HashMap::new()
    };
    let boxed_index: Box<dyn TIndex> = Box::new(index);
    let refcell = RefCell::from(boxed_index);
    let mut _matcher = Matcher::new(
        &refcell // `refcell` does not live long enough
    );
}

playground

我不确定我是否理解出了什么问题(但肯定是有问题)。 'a 在这里是一个 main() 函数作用域,indexrefcell 一直存在直到 main() 退出。 matcher 接受对至少 'a 存在的 RefCell 的引用和对至少 'a 存在的盒子的引用并指向 TIndex 存在的特征对象至少 'a 并且其内部至少存在 'a.

应该如何更改(这里的生命周期声明有什么问题)?

PS。我收到编译器提示(在 main() 关闭 }):

    }
    | -
    | |
    | `refcell` dropped here while still borrowed
    | borrow might be used here, when `refcell` is dropped and runs the destructor for type `RefCell<Box<dyn TIndex<'_>>>`

不确定我是否理解它,因为 refcell 是通过引用传递的(由 _matcher 借用)。

not sure i understand it as refcell is passed by reference (borrowed by _matcher).

问题在于您定义 Matcher 使得 RefCell 的生命周期和 [=12] 的 contents 的生命周期=] 必须相同。

这意味着你告诉 rustc RefCell 必须与它包含的内容一样长,这意味着一旦你将 RefCell 放入 Matcher... 你的程序不能再工作了,因为容器不能正确地比它的内容更长寿。

您需要拆分您的生命周期,以便 rustc 知道它们是如何嵌套的,至少您需要为 &RefCell 及其内容提供不同的生命周期——并告诉 rustc 这些内容比 &RefCell:

pub struct Matcher<'a, 'b> {
    pub index: &'a RefCell<Box<dyn TIndex<'b> + 'b>>
}

impl<'a, 'b: 'a> Matcher<'a, 'b> {
    pub fn new(index: &'a RefCell<Box<dyn TIndex<'b> + 'b>>) -> Self {
        Matcher {
            index
        }
    }
}

拆分 TIndex 的生命周期参数和 TIndex 的生命周期界限可能也是一个好主意(TIndex 的内容应该比 it), 但对于您在此处发布的复制似乎没有必要。