我正在尝试对Rust中的进程使用异步/等待。我正在使用tokiotokio-process:

#![feature(await_macro, async_await, futures_api)]

extern crate tokio;
extern crate tokio_process;

use std::process::Command;
use tokio_process::CommandExt;

fn main() {
    tokio::run_async(main_async());
}

async fn main_async() {
    let out = Command::new("echo")
        .arg("hello")
        .arg("world")
        .output_async();
    let s = await!(out);
}

这是我得到的错误:

error[E0277]: the trait bound `tokio_process::OutputAsync: std::future::Future` is not satisfied
  --> src/main.rs:21:13
   |
21 |     let s = await!(out);
   |             ^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `tokio_process::OutputAsync`
   |
   = note: required by `std::future::poll_with_tls_waker`
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error[E0277]: the trait bound `tokio_process::OutputAsync: std::future::Future` is not satisfied
  --> src/main.rs:21:13
   |
21 |     let s = await!(out);
   |             ^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `tokio_process::OutputAsync`
   |
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

我该如何正确处理?

最佳答案

TL; DR:使用Tokio 0.2或更高版本,它应该可以正常工作。

Tokio 0.1和相关的 crate 是使用 future 0.1 crate 实现的。从概念上讲,此 crate 中的Future特征与标准库中Future特征的版本相似,但细节上却大不相同。 async/await语法是围绕标准库中的特征版本构建的。

使用标准库Future实现了Tokio 0.2和相关的 crate ,并对其进行了重新设计以更好地支持async/await语法。

东京0.2

[dependencies]
tokio = { version = "0.2", features = ["full"] }
use tokio::process::Command;

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let out = Command::new("echo")
        .arg("hello")
        .arg("world")
        .output()
        .await?;

    let s = String::from_utf8_lossy(&out.stdout);

    println!("{}", s);
    Ok(())
}

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/tokio2`
hello world

经过测试:
  • Rustc 1.39.0

  • 东京0.1

    您必须translate between a Future implemented against the trait from the futures 0.1 crate and from the standard library。另外,您需要启动Tokio运行时服务,最好同时运行Tokio 0.1和Tokio 0.3。那是tokio-compat出现的地方:
    [dependencies]
    futures = { version = "0.3", features = ["compat"] }
    tokio-compat = "0.1"
    tokio-process = "0.2"
    
    use futures::compat::Future01CompatExt;
    use std::process::Command;
    use tokio_process::CommandExt;
    
    fn main() {
        tokio_compat::run_std(main_async());
    }
    
    async fn main_async() {
        let out = Command::new("echo")
            .arg("hello")
            .arg("world")
            .output_async();
    
        // Convert future from 0.1 to 0.3
        let s = out.compat().await;
    
        println!("{:?}", s);
    }
    

    % cargo run
        Finished dev [unoptimized + debuginfo] target(s) in 0.07s
         Running `target/debug/tt`
    Ok(Output { status: ExitStatus(ExitStatus(0)), stdout: "hello world\n", stderr: "" })
    

    经过Rust 1.43.0测试

    也可以看看:
  • How do I convert an async / standard library future to futures 0.1?
  • Is there a way that we can convert from futures 0.1 to the standard library futures?
  • Why is a trait not implemented for a type that clearly has it implemented?
  • 关于async-await - 如何在Tokio中使用async/await语法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54853917/

    10-11 10:33