[英]Why does the compiler need that trait hint?
I had this code: 我有这个代码:
pub trait MiddlewareHandler: Clone + Send {
//...probably unimportant for the question
}
#[deriving(Clone)]
pub struct Middleware {
handlers: Vec<Box<MiddlewareHandler>>
}
#[deriving(Clone)]
pub struct Server{
middleware: Middleware
}
This left me with the compiler yelling at me with: 这让我的编译器对我大喊大叫:
src/server.rs:20:31: 20:37 error: the type `server::Server', which does not fulfill `Send`, cannot implement this trait
src/server.rs:20 impl http::server::Server for Server {
^~~~~~
src/server.rs:20:31: 20:37 note: types implementing this trait must fulfill `Send+Sized`
src/server.rs:20 impl http::server::Server for Server {
It took me ages to figure out I had to change Vec<Box<MiddlewareHandler>>
to Vec<Box<MiddlewareHandler + Send>>
so that the final code looks like this: 我花了很长时间才弄清楚我必须将
Vec<Box<MiddlewareHandler>>
更改为Vec<Box<MiddlewareHandler + Send>>
以便最终代码如下所示:
pub trait MiddlewareHandler: Clone + Send {
//...probably unimportant for the question
}
#[deriving(Clone)]
pub struct Middleware {
handlers: Vec<Box<MiddlewareHandler + Send>>
}
#[deriving(Clone)]
pub struct Server{
middleware: Middleware
}
The code compiles now but I quite don't understand what exactly was the problem here. 代码现在编译,但我完全不明白这里究竟是什么问题。 Why
+Send
in the Vec
definition? 为什么
+Send
Vec
定义? I mean, the MiddlewareHandler
trait does already implement Send + Clone
. 我的意思是,
MiddlewareHandler
特性已经实现了Send + Clone
。 It looks rather superfluous to me. 这看起来对我来说是多余的。
Can someone share his wisdom with me why I had to change the code like that? 有人可以与我分享他的智慧为什么我必须改变这样的代码?
Seems like a bug, I filed #15155 . 看起来像一个bug,我提交了#15155 。
The "problem" is the Send
restriction on the http::server::Server
. “问题”是
http::server::Server
上的Send
限制。 The definition is 定义是
pub trait Server: Send + Clone {
meaning the implementee needs to be both Clone
(which is satisfied because you have implemented Clone
via #[deriving(Clone)]
) and Send
. 意味着实现者需要同时
Clone
(因为你通过#[deriving(Clone)]
实现了Clone
而感到满意)和Send
。 The compiler automatically implements Send
for types where the contents satisfies Send
(this detail will be changing with opt-in built-in traits : they will require explicit implementations too), unfortunately the original type is something like 编译器自动实现
Send
了哪些类型的内容满足Send
(这个细节将被改变选择,在内置的特质 :他们将需要明确的实现过),不幸的是,原来的类型是一样的东西
pub struct Middleware {
handlers: Vec<Box<Trait>>
}
which does not implement Send
in general: there's no way for the compiler to know that the erased type in the Box<Trait>
is Send
able, eg it could contain an Rc
, and so be unsafe to transfer into a different task. 一般情况下没有实现
Send
:编译器无法知道Box<Trait>
中的擦除类型是Send
,例如它可能包含一个Rc
,因此转移到另一个任务是不安全的。
The compiler needs to know more information, that is, it needs to have a guarantee that the internal type is Send
, which can be provided by adding more bounds to the trait object: Box<Trait + Send>
... 编译器需要知道更多信息,也就是说,它需要保证内部类型是
Send
,这可以通过向trait对象添加更多边界来提供: Box<Trait + Send>
...
However, in this case, the MiddlewareHandler
trait already has this Send
bound as a supertrait (meaning the contents of the trait object have to satisfy Send
already), so it's weird that the compiler isn't working out that Box<MiddlewareHandler>
is Send
(hence filing the bug). 然而,在这种情况下,
MiddlewareHandler
特质已经有这个Send
绑定为supertrait(意味着性状对象的内容必须满足Send
的话),所以它的怪异编译器不工作的是Box<MiddlewareHandler>
是Send
(因此提交错误)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.