为什么编译器需要特征提示?

时间:2014-06-24 18:54:29

标签: rust traits

我有这段代码:

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
}

这让我的编译器对我大喊大叫:

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 {

我花了很长时间才弄清楚我必须将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
}

代码现在编译但我完全不明白这里究竟是什么问题。为什么+Send定义中的Vec?我的意思是,MiddlewareHandler特征已经实现了Send + Clone。这看起来对我来说是多余的。

有人可以与我分享他的智慧,为什么我必须更改这样的代码?

1 个答案:

答案 0 :(得分:1)

似乎是一个错误,我提交了#15155


&#34;问题&#34;是Send的{​​{1}}限制。定义是

http::server::Server

意味着实施者需要同时为pub trait Server: Send + Clone { (因为您已通过Clone实施Clone而感到满意)和#[deriving(Clone)]。对于内容满足Send的类型,编译器会自动实现Send(此细节将随opt-in built-in traits而变化:它们也需要显式实现),遗憾的是原始类型是

Send

一般不会实现pub struct Middleware { handlers: Vec<Box<Trait>> } :编译器无法知道Send中的已删除类型是否为Box<Trait>,例如它可能包含Send,因此转移到不同的任务是不安全的。

编译器需要了解更多信息,即需要保证内部类型为Rc,这可以通过向特征对象添加更多边界来提供:Send。 ..

但是,在这种情况下,已经Box<Trait + Send>特征MiddlewareHandler绑定为超级特征(意味着特征对象的内容必须满足{{1}因为编译器没有计算SendSend(因此提交错误),这很奇怪。