error: type parameter `D` must be used as the type parameter for some local type
error: type parameter `D` must be used as the type parameter for some local type
我正在使用 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()
}
}
}
}
我收到以下错误:
error: type parameter D
must be used as the type parameter for some
local type (e.g. MyStruct<T>
); only traits defined in the current
crate can be implemented for a type parameter [E0210]
我 运行 rustc --explain E0210
进行解释,如果我的理解是正确的,我需要提供特征 D
作为 impl<D>
的类型参数,但我不明白要提供哪个特征。
我尝试了 impl<D: =()>
,但产生了同样的错误。
当你实现一个特征时 either the trait or the type you are implementing it for must be defined in the same crate。在您的示例中情况并非如此:特征 Responder
由 nickel
定义,而 Result
由 mongodb
.
定义
解决此问题的常用方法是定义您自己的类型,方法是将所需类型包装到具有单个组件的 tuple struct 中(所谓的 newtype 模式):
struct Result(mongodb::error::Result<Option<Document>>);
impl Responder for Result {
...
根据 starblue 的回答,我用元组结构替换了 ApiResponse
和 ApiError
,并重构了我的代码,如下所示:
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))
}
}
我正在使用 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()
}
}
}
}
我收到以下错误:
error: type parameter
D
must be used as the type parameter for some local type (e.g.MyStruct<T>
); only traits defined in the current crate can be implemented for a type parameter [E0210]
我 运行 rustc --explain E0210
进行解释,如果我的理解是正确的,我需要提供特征 D
作为 impl<D>
的类型参数,但我不明白要提供哪个特征。
我尝试了 impl<D: =()>
,但产生了同样的错误。
当你实现一个特征时 either the trait or the type you are implementing it for must be defined in the same crate。在您的示例中情况并非如此:特征 Responder
由 nickel
定义,而 Result
由 mongodb
.
解决此问题的常用方法是定义您自己的类型,方法是将所需类型包装到具有单个组件的 tuple struct 中(所谓的 newtype 模式):
struct Result(mongodb::error::Result<Option<Document>>);
impl Responder for Result {
...
根据 starblue 的回答,我用元组结构替换了 ApiResponse
和 ApiError
,并重构了我的代码,如下所示:
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))
}
}