我正在尝试编写一个支持继续传递风格的“reduce”函数,可以在任何时候恢复。我已经有一个可用的版本,但是如果我想使用某个状态的借用,就需要显式地编写该函数的新版本。
Rust Playground链接
这是我想编写的函数版本,其中我可以将
我该如何编写非专业版本的函数,并传递像
即使我没有为
因为我调用的第三方 API 函数需要这样做,所以
fn reduce_async_with_store<'a, I, A, F, C>(
store: &mut Store,
mut iterator: I,
accumulator: A,
mut f: F,
continuation: C,
) where
I: Iterator + 'a,
F: FnMut(&mut Store, I::Item, A, Box<dyn FnOnce(&mut Store, A) + 'a>) + Clone + 'a,
C: FnOnce(&mut Store, A) + 'a,
{
match iterator.next() {
None => continuation(store, accumulator),
Some(item) => {
let next: Box<dyn FnOnce(&mut Store, A) + 'a> = {
let f = f.clone();
Box::new(move |store, accumulator| {
reduce_async_with_store(store, iterator, accumulator, f, continuation)
})
};
f(store, item, accumulator, next);
}
}
}
fn some_operation(state: &mut Store, continuation: Box<dyn FnOnce(&mut Store) + 'static>) {
let mut new_state = Store { foo: state.foo };
continuation(&mut new_state);
}
#[derive(Debug)]
pub struct Store {
foo: u8,
}
fn main() {
let mut some_state = Store { foo: 0 };
let arr = vec![1u8, 2u8, 3u8];
reduce_async_with_store(
&mut some_state,
arr.into_iter(),
Vec::new(),
|store, item, mut acc, continuation| {
println!("Item: {}", item);
store.foo += item;
acc.push(item);
some_operation(
store,
Box::new(move |stor| {
continuation(stor, acc);
}),
);
},
|store, acc| {
println!("Done!! {:?} {:?}", store, acc);
},
)
}
这是我想编写的函数版本,其中我可以将
Store
作为累加器的一部分传递并获取它,但是,如果我这样做,会出现cannot infer an appropriate lifetime due to conflicting requirements
的错误提示。
Rust Playground链接
fn reduce_async<'a, I, A, F, C>(mut iterator: I, accumulator: A, mut f: F, continuation: C)
where
I: Iterator + 'a,
F: FnMut(I::Item, A, Box<dyn FnOnce(A) + 'a>) + Clone + 'a,
C: FnOnce(A) + 'a,
{
match iterator.next() {
None => continuation(accumulator),
Some(item) => {
let next: Box<dyn FnOnce(A) + 'a> = {
let f = f.clone();
Box::new(move |accumulator| reduce_async(iterator, accumulator, f, continuation))
};
f(item, accumulator, next);
}
}
}
fn some_operation(state: &mut Store, continuation: Box<dyn FnOnce(&mut Store) + 'static>) {
let mut new_state = Store { foo: state.foo };
continuation(&mut new_state);
}
#[derive(Debug)]
pub struct Store {
foo: u8,
}
fn main() {
let mut some_state = Store { foo: 0 };
let arr = vec![1u8, 2u8, 3u8];
reduce_async(
arr.into_iter(),
(&mut some_state, Vec::new()),
|item, mut acc, continuation| {
let (store, vec) = acc;
println!("Item: {}", item);
store.foo += item;
vec.push(item);
some_operation(
store,
Box::new(move |store| {
continuation((store, vec));
}),
);
},
|(store, vec)| {
println!("Done!! {:?} {:?}", store, vec);
},
)
}
我该如何编写非专业版本的函数,并传递像
&mut Store
这样的内容,同时要符合 Rust 中的生命周期?即使我没有为
&mut Store
指定显式生命周期,并且它可以存活到 'static
,我的第一个例子中的 reduce_async_with_store
为什么被允许?因为我调用的第三方 API 函数需要这样做,所以
some_operation
接受一个包含闭包的盒子。 我最终想要用异步迭代器替换这段代码,但是我使用的库尚未支持 futures。