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
);
}
我不确定我是否理解出了什么问题(但肯定是有问题)。
'a
在这里是一个 main()
函数作用域,index
和 refcell
一直存在直到 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), 但对于您在此处发布的复制似乎没有必要。
代码如下(有 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
);
}
我不确定我是否理解出了什么问题(但肯定是有问题)。
'a
在这里是一个 main()
函数作用域,index
和 refcell
一直存在直到 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), 但对于您在此处发布的复制似乎没有必要。