trait bound `futures::Future<Item=Arc<T>, Error=Box<Error + Send>>: Send` 不满足
The trait bound `futures::Future<Item=Arc<T>, Error=Box<Error + Send>>: Send` is not satisfied
我有以下(简化的)代码片段,我正在尝试 运行 CpuPool 上的未来:
use futures::{self, Future, IntoFuture};
use std::error;
use futures_cpupool::CpuPool;
pub struct Store<T: 'static + Send + Sync> {
inner: Arc<StoreInner<T, C, SerDe, P>>,
}
struct StoreInner<T: 'static + Send + Sync> {
read_thread_pool: CpuPool,
}
impl<T: 'static + Send + Sync> Store<T> {
pub fn get(self, obj_id: String) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>>>
where
T: for<'de> BinaryDeserialize<'de>,
{
let latest_version_id =
futures::future::ok(()).and_then(move |_| self.get_latest_version_id(&obj_id));
let latest_version = latest_version_id.and_then(
move |version_id| -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>>> {
self.get_version(&obj_id, version_id)
},
);
Box::new(self.inner.read_thread_pool.spawn(latest_version))
}
}
但是,当我尝试编译时出现以下错误。
error[E0277]: the trait bound `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>: std::marker::Send` is not satisfied
--> src/store/mod.rs:181:46
|
181 | Box::new(self.inner.read_thread_pool.spawn(Box::new(latest_version)))
| ^^^^^ `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>`
= note: required because it appears within the type `std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>`
= note: required because it appears within the type `futures::future::chain::Chain<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>`
= note: required because it appears within the type `futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>>`
= note: required because it appears within the type `std::boxed::Box<futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>>`
代码看起来很无辜,以后的Item
和Error
都是Send
。我不知道为什么会出现此错误。
我 认为 这里的问题是 Future
特征不是 Send
只是因为它的 Item
和 Error
都是 Send
- 你必须明确指定它。
如果 Future
是一个结构,我认为编译器可以自动派生 Send
,但它不是,所以不能。
我修复了编译错误并添加了 + Send
到您定义的 Future
类型,现在它可以编译(除了没有 main
函数之外) :
extern crate futures;
extern crate futures_cpupool;
use futures::Future;
use std::error;
use std::sync::Arc;
use futures_cpupool::CpuPool;
pub struct Store {
inner: Arc<StoreInner>,
}
struct StoreInner {
read_thread_pool: CpuPool,
}
impl Store {
pub fn get<T: 'static + Send + Sync>(
self,
obj_id: String,
) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send> {
let latest_version_id =
futures::future::ok(()).and_then(move |_| self.get_latest_version_id(&obj_id));
let latest_version =
latest_version_id
.and_then(
move |version_id| -> Box<
Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send,
> { self.get_version(&obj_id, version_id) },
);
Box::new(self.inner.read_thread_pool.spawn(latest_version))
}
pub fn get_latest_version_id(
&self,
obj_id: &String,
) -> Box<Future<Item = String, Error = Box<error::Error + Send>> + Send> {
unimplemented!();
}
pub fn get_version<T: 'static + Send + Sync>(
&self,
obj_id: &String,
version_id: String,
) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send> {
unimplemented!();
}
}
我有以下(简化的)代码片段,我正在尝试 运行 CpuPool 上的未来:
use futures::{self, Future, IntoFuture};
use std::error;
use futures_cpupool::CpuPool;
pub struct Store<T: 'static + Send + Sync> {
inner: Arc<StoreInner<T, C, SerDe, P>>,
}
struct StoreInner<T: 'static + Send + Sync> {
read_thread_pool: CpuPool,
}
impl<T: 'static + Send + Sync> Store<T> {
pub fn get(self, obj_id: String) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>>>
where
T: for<'de> BinaryDeserialize<'de>,
{
let latest_version_id =
futures::future::ok(()).and_then(move |_| self.get_latest_version_id(&obj_id));
let latest_version = latest_version_id.and_then(
move |version_id| -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>>> {
self.get_version(&obj_id, version_id)
},
);
Box::new(self.inner.read_thread_pool.spawn(latest_version))
}
}
但是,当我尝试编译时出现以下错误。
error[E0277]: the trait bound `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>: std::marker::Send` is not satisfied
--> src/store/mod.rs:181:46
|
181 | Box::new(self.inner.read_thread_pool.spawn(Box::new(latest_version)))
| ^^^^^ `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>`
= note: required because it appears within the type `std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>`
= note: required because it appears within the type `futures::future::chain::Chain<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>`
= note: required because it appears within the type `futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>>`
= note: required because it appears within the type `std::boxed::Box<futures::AndThen<futures::AndThen<futures::FutureResult<(), std::boxed::Box<std::error::Error + std::marker::Send>>, std::boxed::Box<futures::Future<Item=serde::export::Option<std::string::String>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:177:67: 177:115 self:_, obj_id:_]>, std::boxed::Box<futures::Future<Item=std::sync::Arc<T>, Error=std::boxed::Box<std::error::Error + std::marker::Send>>>, [closure@src/store/mod.rs:178:56: 180:10 self:_, obj_id:_]>>`
代码看起来很无辜,以后的Item
和Error
都是Send
。我不知道为什么会出现此错误。
我 认为 这里的问题是 Future
特征不是 Send
只是因为它的 Item
和 Error
都是 Send
- 你必须明确指定它。
如果 Future
是一个结构,我认为编译器可以自动派生 Send
,但它不是,所以不能。
我修复了编译错误并添加了 + Send
到您定义的 Future
类型,现在它可以编译(除了没有 main
函数之外) :
extern crate futures;
extern crate futures_cpupool;
use futures::Future;
use std::error;
use std::sync::Arc;
use futures_cpupool::CpuPool;
pub struct Store {
inner: Arc<StoreInner>,
}
struct StoreInner {
read_thread_pool: CpuPool,
}
impl Store {
pub fn get<T: 'static + Send + Sync>(
self,
obj_id: String,
) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send> {
let latest_version_id =
futures::future::ok(()).and_then(move |_| self.get_latest_version_id(&obj_id));
let latest_version =
latest_version_id
.and_then(
move |version_id| -> Box<
Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send,
> { self.get_version(&obj_id, version_id) },
);
Box::new(self.inner.read_thread_pool.spawn(latest_version))
}
pub fn get_latest_version_id(
&self,
obj_id: &String,
) -> Box<Future<Item = String, Error = Box<error::Error + Send>> + Send> {
unimplemented!();
}
pub fn get_version<T: 'static + Send + Sync>(
&self,
obj_id: &String,
version_id: String,
) -> Box<Future<Item = Arc<T>, Error = Box<error::Error + Send>> + Send> {
unimplemented!();
}
}