如何解决Rust,如何执行基本的递归异步?
我只是在做一些快速实验以尝试学习 Rust 语言,我已经完成了一些成功的异步测试,这是我的起点:
use async_std::task;
use futures;
use std::time::SystemTime;
fn main() {
let Now = SystemTime::Now();
task::block_on(async {
let mut fs = Vec::new();
let sum = 100000000;
let chunks: u64 = 5; //only valid for factors of sum
let chunk_size: u64 = sum/chunks;
for n in 1..=chunks {
fs.push(task::spawn(async move {
add_range((n - 1) * chunk_size + 1,n * chunk_size + 1)
}));
}
let vals = futures::future::join_all(fs).await;
// 5000000050000000 for this configuration of inputs
println!("{}",vals.iter().sum::<u64>());
});
println!("{}ms",Now.elapsed().unwrap().as_millis());
}
fn add_range(start: u64,end: u64) -> u64 {
println!("{},{}",start,end);
let mut total: u64 = 0;
for n in start..end {
total += n;
}
return total;
}
通过更改 chunks
的值,您可以更改 task::spawn
的数量。现在,而不是一组扁平的工作人员,我希望 add_range
函数是递归的,并根据输入不断分叉工作人员,但是在编译器错误之后,我让自己陷入了困境:
use async_std::task;
use futures;
use std::future::Future;
use std::pin::Pin;
fn main() {
let pin_Box_u64 = task::block_on(add_range(0,10,1,1001));
println!("{}",pin_Box_u64/*how do i get u64 out of this*/)
}
// recursively calls itself in a branching tree structure
// forking off more worker threads
async fn add_range(
depth: u64,chunk_split: u64,chunk_size: u64,start: u64,end: u64,) -> Pin<Box<dyn Future<Output = u64>>> {
println!("{},{},depth,end);
// if the range of start to end is more than the allowed
// chunk_size then fork off more workers dividing
// the work up further.
if end - start > chunk_size {
let mut fs = Vec::new();
let next_chunk_size = (end - start) / chunk_split;
for n in 0..chunk_split {
let s = start + (next_chunk_size * n);
let mut e = start + (next_chunk_size * (n + 1));
if e > end {
e = end;
}
// spawn more workers
fs.push(task::spawn(add_range(depth + 1,chunk_split,chunk_size,s,e)));
}
return Box::pin(async move {
// join workers back up and do joining sum.
return futures::future::join_all(fs).await.iter().map(/*how do i get u64s out of here*/).sum::<u64>();
});
} else {
// else the work is less than the allowed chunk_size
// so lets Now do the actual sum for my chunk
let mut total: u64 = 0;
for n in start..end {
total += n;
}
return Box::pin(async move { total });
}
}
我已经玩了一段时间了,但我觉得我对编译器错误越来越迷茫了。
解决方法
需要对返回的future进行装箱,否则编译器无法确定返回类型的大小。
可以在此处找到其他上下文:https://rust-lang.github.io/async-book/07_workarounds/04_recursion.html
use std::pin::Pin;
use async_std::task;
use futures::Future;
use futures::FutureExt;
fn main() {
let pin_box_u64 = task::block_on(add_range(0,10,1,1001));
println!("{}",pin_box_u64)
}
// recursively calls itself in a branching tree structure
// forking off more worker threads
fn add_range(
depth: u64,chunk_split: u64,chunk_size: u64,start: u64,end: u64,) -> Pin<Box<dyn Future<Output = u64> + Send + 'static>> {
println!("{},{},{}",depth,start,end);
// if the range of start to end is more than the allowed
// chunk_size then fork off more workers dividing
// the work up further.
if end - start > chunk_size {
let mut fs = Vec::new();
let next_chunk_size = (end - start) / chunk_split;
for n in 0..chunk_split {
let s = start + (next_chunk_size * n);
let mut e = start + (next_chunk_size * (n + 1));
if e > end {
e = end;
}
// spawn more workers
fs.push(task::spawn(add_range(
depth + 1,chunk_split,chunk_size,s,e,)));
}
// join workers back up and do joining sum.
return futures::future::join_all(fs)
.map(|v| v.iter().sum::<u64>())
.boxed();
} else {
// else the work is less than the allowed chunk_size
// so lets now do the actual sum for my chunk
let mut total: u64 = 0;
for n in start..end {
total += n;
}
return futures::future::ready(total).boxed();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。