我想在一个结构体中有一个函数,它接受一个状态并返回一个迭代器。到目前为止,这是可行的,除非我想让迭代器从状态中借用,这应该是可以的,但我不知道如何表达生存期。
第一个例子运行得很好,因为Vec
被克隆了,但是出于性能考虑,我不想克隆。
use std::fmt::Display;
struct State {
items: Vec<i32>,
}
struct HasIteratorFunction<T: Display, I: Iterator<Item = T>> {
iterator: Box<dyn Fn(&State) -> I>,
}
impl<T: Display, I: Iterator<Item = T>> HasIteratorFunction<T, I> {
fn print_items(&self, state: &State) {
for item in (self.iterator)(state) {
println!("{}", item);
}
}
}
fn main() {
// this works
let it = HasIteratorFunction {
iterator: Box::new(|state| state.items.clone().into_iter())
};
it.print_items(&State { items: vec![1, 2, 3] });
// this doesn't
let it_without_cloning = HasIteratorFunction {
iterator: Box::new(|state| state.items.iter())
};
it_without_cloning.print_items(&State { items: vec![4, 5, 6] });
}
真实的的代码将更加通用,因此返回切片而不是通用迭代器将不起作用。
2条答案
按热度按时间bprjcwpo1#
在
HasIteratorFunction
结构体中存储的回调函数中为State
添加一个显式的生存期,并为相同的生存期添加一个绑定到I
的生存期。Playground.
44u64gxh2#
你可以实现类似的东西,但不能用闭包,也不能完全按照要求(注意我添加了
copied()
):在未来,你可能能够更好地实现这一点,也许没有
copied()
,但目前,由于Fn
特征的设计方式和类型系统的限制,恕我直言,这是你能得到的最好的。