gpt4 book ai didi

asynchronous - 如何使用 tokio 0.1 和异步函数递归删除目录?

转载 作者:行者123 更新时间:2023-11-29 08:28:10 25 4
gpt4 key购买 nike

我想编写一个程序,在 Rust 1.39 中使用异步函数递归删除目录。

作为第一步,我尝试了以下代码,但它没有编译:

use std::env;
use failure::Error;
use futures::Future;
use std::path::PathBuf;
use tokio::prelude::*;

fn walk(path: PathBuf) -> Box<dyn Future<Item = (), Error = Error> + Send> {
let task = tokio::fs::read_dir(path)
.flatten_stream()
.for_each(move |entry| {
let filepath = entry.path();
if filepath.is_dir() {
future::Either::A(walk(filepath))
} else {
println!("File: {:?}", filepath);
future::Either::B(future::ok(()))
}
})
.map_err(Error::from)
.and_then(|_| {
println!("All tasks done");
});
Box::new(task)
}

fn main() -> Result<(), std::io::Error> {
let args: Vec<String> = env::args().collect();
let dir = &args[1];
let t = walk(PathBuf::from(&dir)).map_err(drop);
tokio::run(t);
Ok(())
}

当我运行 cargo build 时,我得到以下输出:

error[E0220]: associated type `Item` not found for `core::future::future::Future`
--> src\main.rs:10:42
|
10 | fn walk(path: PathBuf) -> Box<dyn Future<Item = (), Error = Error> + Send> {
| ^^^^^^^^^ associated type `Item` not found

error[E0220]: associated type `Error` not found for `core::future::future::Future`
--> src\main.rs:10:53
|
10 | fn walk(path: PathBuf) -> Box<dyn Future<Item = (), Error = Error> + Send> {
| ^^^^^^^^^^^^^ associated type `Error` not found

error[E0191]: the value of the associated type `Output` (from the trait `core::future::future::Future`) must be specified
--> src\main.rs:10:31
|
10 | fn walk(path: PathBuf) -> Box<dyn Future<Item = (), Error = Error> + Send> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated type `Output` must be specified

cargo .toml:

[dependencies]
async-std = "1.0.1"
failure = "0.1.6"
futures = "0.3.1"
tokio = "0.1.22"

有什么帮助吗?

最佳答案

您正在使用 futures 0.3,tokio 0.1 尚不支持。相反,导入 Tokio 并使用其 prelude 模块,该模块重新导出它支持的 futures 版本:

use std::{env, path::PathBuf};
use tokio::prelude::*; // 0.1.22

type Error = Box<dyn std::error::Error + Send + Sync>;

fn walk(path: PathBuf) -> Box<dyn Future<Item = (), Error = Error> + Send> {
let task = tokio::fs::read_dir(path)
.flatten_stream()
.map_err(Error::from)
.for_each(|entry| {
let filepath = entry.path();
if filepath.is_dir() {
future::Either::A(walk(filepath))
} else {
println!("File: {:?}", filepath);
future::Either::B(future::ok(()))
}
})
.inspect(|_| {
println!("All tasks done");
});
Box::new(task)
}

fn main() -> Result<(), std::io::Error> {
let args: Vec<String> = env::args().collect();
let dir = &args[1];
let t = walk(PathBuf::from(&dir)).map_err(drop);
tokio::run(t);
Ok(())
}

您还需要在 flatten_stream 之后转换错误,并且不能将 and_thenprintln! 一起使用,因为它不会返回 future 。使用 inspect 进行副作用调试。

按照惯例,您不需要收集所有参数来使用一个参数(使用 Iterator::nth),也不需要要求 PathBuf作为论据。不清楚为什么要从 main 返回 Result,因为它永远不可能是 Err

另见:

关于asynchronous - 如何使用 tokio 0.1 和异步函数递归删除目录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58824205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com