我在数据结构中使用trait对象并将其正确传递给函数时遇到了一些问题。
假设我有一个自定义trait MyTrait
,一个定义为
struct MyStruct<'a> {
my_stuff: HashMap<String, Box<dyn MyTrait + 'a>>
}
另外,我有一个函数需要接受一个满足MyTrait
的向量,并以只读方式对它们进行操作。我现在把它定义为
fn do_something(things: Vec<&Box<dyn MyTrait>>) {
// We'll do something here that only READS data off each thing, no modification
}
现在假设我得到一个字符串向量ids: Vec<String>
,我想从my_stuff
Map中获取trait对象的对应向量,以便将其传递给do_something
函数。我试过这样的东西:
let my_vec: Vec<&Box<dyn MyTrait>> = my_stuff
.iter()
.filter(|(id, _m)| ids.contains(id))
.map(|(_id, m)| m)
.collect();
在我的真实的问题中,到目前为止对我来说是编译的。然而,当我尝试执行do_something(my_vec);
时,它会斥责我:
.map(|(_id, m)| m)
^ returning this value requires that `'a` must outlive `'static`
我已经四处寻找并尝试了很多东西,现在有点陷入僵局,因为我强烈地感觉到我的问题将从使用trait对象中受益,并且这种将实现MyTrait
的事物的向量传递给函数以读取数据并计算某些东西的方案是必要的,但我无法让它工作。我欢迎任何和所有的建议,可能会纠正这一点,为这个Rust新手。
1条答案
按热度按时间tv6aics11#
问题是
do_something()
只接受dyn MyTrait + 'static
,所以生存期不够长。将其签名更改为fn do_something(things: Vec<&Box<dyn MyTrait + '_>>)
,它就会工作。更好的例子是
Vec<&dyn MyTrait>
。然后保存一个间接寻址,也不需要显式指定生存期--它是隐式的。您还可以将do_something()
更改为impl Iterator
或impl IntoIterator
,假设它不需要特定的Vec
,则不需要collect()
。