简体   繁体   English

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

[英]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.

相关问题 为什么编译器需要一个 trait 的实现来调用默认的自由函数? - Why does the compiler need an implementation of a trait to call a default free function? 为什么我的特质需要一个终身参数? - Why does my trait need a lifetime parameter? 为什么 Rust 编译器需要 Option&lt;&amp;impl Trait&gt; 的类型注释? - Why does the rust compiler require a type annotation for Option<&impl Trait>? 为什么编译器会推断出特征及其实现的不同生命周期? - Why does the compiler infer different lifetimes for a trait and its implementation? 为Vec添加实现后,为什么Rust编译器不使用预期的trait实现 <T> ? - Why does the Rust compiler not use the expected trait implementation once I add an implementation for Vec<T>? 为什么编译器不推断impl特质返回值的关联类型的具体类型? - Why does the compiler not infer the concrete type of an associated type of an impl trait return value? 实现Sync特性是否会更改编译器输出? - Does implementing the Sync trait change the compiler output? 为什么Rust编译器不能使用From特性将库错误转换为我的错误? - Why does the Rust compiler not convert from a library error to my error using the From trait? 为什么我们需要重复 trait 定义中指定的 trait bound? - Why we need to repeat trait bounds that were specified in trait definitions? 为什么特征中的泛型方法需要调整特征对象的大小? - Why does a generic method inside a trait require trait object to be sized?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM