我试图实现一种类型,它将在潮汐中对我的响应“强制执行”一些模式,但是一直得到“来自特性的项只能使用.”。编译器错误
#![feature(async_await, futures_api, await_macro, arbitrary_self_types)]
#![allow(proc_macro_derive_resolution_fallback)]
use serde_derive::Serialize;
use tide::{body::Json, IntoResponse, Response};
#[derive(Serialize)]
struct Document<Attrs, Rels> {
data: PrimaryData<Attrs, Rels>,
}
#[derive(Serialize)]
struct PrimaryData<Attrs, Rels> {
id: i32,
kind: String,
attributes: Attrs,
relationships: Rels,
}
trait IntoPrimaryData: Send {
type Attrs: serde::Serialize;
type Rels: serde::Serialize;
fn into_primary_data(self) -> PrimaryData<Self::Attrs, Self::Rels>;
}
struct ServiceResponse<T: IntoPrimaryData>(T);
impl<T: IntoPrimaryData> IntoResponse for ServiceResponse<T> {
fn into_response(self) -> Response {
Json(Document {
data: self.0.into_primary_data(),
})
.with_status(http::status::StatusCode::OK)
.into_response()
}
}
#[derive(Serialize)]
struct User {
id: i32,
primary_email: String,
}
#[derive(Serialize)]
struct UserAttrs {
primary_email: String,
}
impl IntoPrimaryData for User {
type Attrs = UserAttrs;
type Rels = ();
fn into_primary_data(self) -> PrimaryData<Self::Attrs, Self::Rels> {
PrimaryData {
id: self.id,
kind: "user".into(),
attributes: UserAttrs {
primary_email: self.primary_email,
},
relationships: (),
}
}
}
fn main() {}[dependencies]
tide = "0.0.5"
http = "0.1.16"
serde = "1.0.89"
serde_derive = "1.0.89"编译器返回错误。
error[E0599]: no method named `with_status` found for type `tide::body::Json<Document<<T as IntoPrimaryData>::Attrs, <T as IntoPrimaryData>::Rels>>` in the current scope
--> src/main.rs:34:10
|
34 | .with_status(http::status::StatusCode::OK)
| ^^^^^^^^^^^
|
= note: the method `with_status` exists but the following trait bounds were not satisfied:
`tide::body::Json<Document<<T as IntoPrimaryData>::Attrs, <T as IntoPrimaryData>::Rels>> : tide::response::IntoResponse`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `with_status`, perhaps you need to implement it:
candidate #1: `tide::response::IntoResponse`我不知道为什么会出现这个错误,但我觉得这与行data: self.0.into_primary_data()不够“具体”有关,也不知道Self::Attrs和Self::Rels的类型是什么。然而,我知道我也得到了同样的错误(减去关于“特性项只能是.”的帮助提示)如果其中一个嵌套类型没有实现serde::Serialize,但据我所知,我已经在所有需要它们的地方添加了这些边界。
我已经尝试过用上百万种方式来做这些事情,但我似乎想不出一个方法来为我的反应找到一个规范化的结构。
我用的是rustc 1.34.0-nightly (02c4c2892 2019-02-26)
发布于 2019-03-14 00:48:51
您没有正确地指定关联类型的完整界限。
Json只在其包含的类型同时实现Send和Serialize时才实现Serialize。
impl<T: Send + Serialize> IntoResponse for Json<T>您需要在关联类型的边界中包括Send:
trait IntoPrimaryData: Send {
type Attrs: serde::Serialize + Send;
// ^^^^^^
type Rels: serde::Serialize + Send;
// ^^^^^^
fn into_primary_data(self) -> PrimaryData<Self::Attrs, Self::Rels>;
}调试步骤
这一行错误消息似乎很有希望:
the method `with_status` exists but the following trait bounds were not satisfied:
`tide::body::Json<Document<<T as IntoPrimaryData>::Attrs, <T as IntoPrimaryData>::Rels>> : tide::response::IntoResponse`这说明我们可以调用with_status,只是编译器不知道该类型实现了该特性。从那里,我查看了Json的文档,看看它是否实现了IntoRespose,如果实现了,在什么条件下:
impl<T: Send + Serialize> IntoResponse for Json<T>基于此,我们知道这个T必须是PrimaryData<T::Attrs, T::Rels>,并且必须实现Send + Serialize。
我们看到PrimaryData派生了Serialize
#[derive(Serialize)]
struct PrimaryData<Attrs, Rels> {根据现有的知识,我知道大多数derived特征都要求所有泛型类型也实现该特性。这一点不太明显,但Send也是如此。
这样,就可以证明Attrs和Rels的特定类型实现了Serialize和Send。关联类型边界处理一个,而不处理另一个。
决定在哪里放置边界是一个意图和风格的问题--他们可以使用函数、impl块或特征。由于这个特性已经提到了Serialize,所以添加额外的绑定似乎是一个很自然的地方。
我还犯了一个很大的错误--我假设您已经正确地指定了边界,并且正在运行编译器限制 (也是)。只有当我试图应用建议的复制时,我才意识到界限是不正确的。
另请参阅:
https://stackoverflow.com/questions/55144134
复制相似问题