【问题标题】:error: type parameter `D` must be used as the type parameter for some local type错误:类型参数`D`必须用作某些本地类型的类型参数
【发布时间】:2016-05-23 16:10:39
【问题描述】:

我正在使用 Nickel.rs 和 MongoDB 来构建 RESTful api。 我想为mongodb::error::Result<Option<bson::Document>> 类型实现一个通用的Responder

这是我根据我为Responder找到的示例编写的实现:

impl<D> Responder<D> for Result<Option<Document>> {

    fn respond<'a>(self, mut response: Response<'a, D>) -> MiddlewareResult<'a, D> {
        response.set(MediaType::Json);

        match self {
            Ok(Some(doc))=>{
                ApiResponse{data: Bson::Document(doc).to_json()}.to_json()
            },
            Ok(None)=>{
                response.set(StatusCode::NotFound);
                ApiError{error: "Not found".to_string()}.to_json()
            },
            Err(e)=>{
                response.set(StatusCode::InternalServerError);
                ApiError{error: format!("{}",e)}.to_json()
            }

        }
    }
}

我收到以下错误:

错误:类型参数D 必须用作某些类型的参数 本地类型(例如MyStruct&lt;T&gt;);仅在当前定义的特征 可以为类型参数实现 crate [E0210]

我运行rustc --explain E0210 进行解释,如果我的理解是正确的,我需要提供一个特征D 作为impl&lt;D&gt; 的类型参数,但我不明白要提供哪个特征。

我尝试了impl&lt;D: =()&gt;,但产生了同样的错误。

【问题讨论】:

  • Responder 特质从何而来?
  • “必须在与 impl 相同的 crate 中定义 trait 或要实现它的类型 [...]”doc.rust-lang.org/book/…
  • 响应者特质来自镍:docs.nickel.rs/nickel/trait.Responder.html
  • @starblue:这是一个答案。你也可以扩展它来解释元组结构,它可以用来将一个类型包装在一个本地类型中,从而用它来实现特征。

标签: mongodb rust nickel


【解决方案1】:

当你实现一个特征时,然后either the trait or the type you are implementing it for must be defined in the same crate。在您的示例中,情况并非如此:特征Respondernickel 定义,Resultmongodb 定义。

解决此问题的常用方法是定义您自己的类型,通过将所需类型包装到带有单个组件的 tuple struct 中(所谓的 newtype 模式):

struct Result(mongodb::error::Result<Option<Document>>);

impl Responder for Result {
    ...

【讨论】:

  • 阅读您的评论后,我理解了解释的含义,并且我所做的几乎与您在回答中描述的完全一样。非常感谢!
【解决方案2】:

根据starblue的回答,我用元组结构替换了ApiResponseApiError,并重构了我的代码如下:

struct ApiResponse<T>(T);

impl<D> Responder<D> for ApiResponse<Result<Option<Document>>> {

    fn respond<'a>(self, mut response: Response<'a, D>) -> MiddlewareResult<'a, D> {

        let mut d = BTreeMap::new();
        match self.0 {
            Ok(Some(doc))=>{
                d.insert("data".to_string(),Bson::Document(doc).to_json());
            },
            Ok(None)=>{
                response.set(StatusCode::NotFound);
                d.insert("error".to_string(),"Not Found".to_json());
            },
            Err(e)=>{
                response.set(StatusCode::InternalServerError);
                d.insert("error".to_string(),format!("{}",e).to_json());
            }

        }
        response.set(MediaType::Json);
        response.send(Json::Object(d))
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多