首页 > 解决方案 > 无法 tokio::run a boxed Future 因为 trait bound Send 不满足

问题描述

我有一个函数可以选择运行未来或什么都不做,具体取决于参数。我尝试将 a 放在Box将返回的两个期货中,atokio::prelude::future::Done<Item=(), Error=()>立即解析为Ok(()),以及tokio::timer::Delay我正在使用and_thenandmap_err将两者都转换为Item和。当我尝试使用.Error()tokio::run

extern crate tokio;

use std::time::{Duration, Instant};
use tokio::prelude::*;
use tokio::timer;

fn main() {
    tokio::run(foo(12));
}

fn foo(x: i32) -> Box<Future<Item = (), Error = ()>> {
    if x == 0 {
        Box::new(
            timer::Delay::new(Instant::now() + Duration::from_secs(5))
                .and_then(|_| Ok(()))
                .map_err(|_| ()),
        )
    } else {
        Box::new(future::result(Ok(())))
    }
}

这无法编译并显示以下错误消息:

error[E0277]: the trait bound `tokio::prelude::Future<Error=(), Item=()>: std::marker::Send` is not satisfied
 --> src/main.rs:8:5
  |
8 |     tokio::run(foo(12));
  |     ^^^^^^^^^^ `tokio::prelude::Future<Error=(), Item=()>` cannot be sent between threads safely
  |
  = help: the trait `std::marker::Send` is not implemented for `tokio::prelude::Future<Error=(), Item=()>`
  = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<tokio::prelude::Future<Error=(), Item=()>>`
  = note: required because it appears within the type `std::boxed::Box<tokio::prelude::Future<Error=(), Item=()>>`
  = note: required by `tokio::run`

似乎Box<Future...>没有实现Send,这对我来说没有意义。由于Future我返回的类型都实现了Send,所以在我看来Box应该,因为impl Send for Box<T> where T: Send是标准库中的自动实现。我在这里想念什么?

标签: rustrust-tokio

解决方案


我意识到我需要在返回类型中指定Foo未来是Send. 这编译:

extern crate tokio;

use std::time::{Duration, Instant};
use tokio::prelude::*;
use tokio::timer;

fn main() {
    tokio::run(foo(12));
}

fn foo(x: i32) -> Box<Future<Item = (), Error = ()> + Send> { // note the + Send at the end of this line
    if x == 0 {
        Box::new(
            timer::Delay::new(Instant::now() + Duration::from_secs(5))
                .and_then(|_| Ok(()))
                .map_err(|_| ()),
        )
    } else {
        Box::new(future::result(Ok(())))
    }
}

推荐阅读