为什么 trait 没有为明确实现的类型实现? [英] Why is a trait not implemented for a type that clearly has it implemented?

查看:30
本文介绍了为什么 trait 没有为明确实现的类型实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 Diesel 来查询 MySQL 数据库并使用带有 火箭.

I'm trying to use Diesel to query a MySQL database and display the results with a Handlebars template with Rocket.

我在 models.rs

#[derive(Queryable, Serialize)]
pub struct Post {
    pub id: i32,
    pub title: String,
    pub text: String,
    pub published: bool,
}

cargo run 输出:

  --> src/main.rs:69:5
   |
69 |     Template::render("index", &results)
   |     ^^^^^^^^^^^^^^^^ the trait `serde::ser::Serialize` is not implemented for `tasty::models::Post`
   |
   = note: required because of the requirements on the impl of `serde::ser::Serialize` for `std::vec::Vec<tasty::models::Post>`
   = note: required by `rocket_contrib::Template::render`

在我的 Cargo.toml 中,我有这个:

In my Cargo.toml, I have this:

[dependencies]
chrono = "0.3.0"
rocket = "0.2.8"
rocket_codegen = "0.2.8"
serde = "1.0.8"
serde_derive = "1.0.8"
serde_json = "1.0.2"
mysql = "11.1.2"
diesel = { version = "0.13.0", features = ["mysql","chrono"] }
diesel_codegen = { version = "0.13.0", features = ["mysql"] }
dotenv = "0.10.0"

[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["handlebars_templates"]

我已经读到 Diesel 目前不支持 Serialize,但我不确定.

I have read that Diesel does not support Serialize at the moment, but I am not sure.

推荐答案

一般问题是代码有多个版本的 crate,每个版本提供不同版本的特征.Rust 允许这是一件好事但错误周围的消息令人困惑.

The general problem is that the code has multiple versions of the crate, each providing a different version of the traits. The fact that Rust allows this is a good thing, but the error messages around it are confusing.

您的 crate 实现了版本 A 的 Serialize,但库在公共接口中使用了版本 B.这些特征不兼容,因此当您将实现 Serialize@A 的类型传递给需要 Serialize@B 的函数时,编译器会阻止您.

Your crate implements Serialize from version A but the library is using version B in a public interface. These traits are not compatible, so when you pass your type implementing Serialize@A to the function requiring Serialize@B, the compiler stops you.

虽然您的示例是关于不同特征的,但对于从板条箱重新导出的类型也可能发生这种情况.

While your example is about different traits, it's also possible for this to occur for types which have been re-exported from a crate.

cargo tree,从 Rust 1.44 对于验证这是您的问题非常有用.它显示了您的所有依赖项及其版本.它甚至有一个 -d 标志来显示重复的依赖项!该模式未在此处显示,但非常有用.

cargo tree, available starting in Rust 1.44 is highly useful to verify this is your problem. It shows all of your dependencies and their versions. It even has a -d flag to show duplicate dependencies! That mode isn't shown here, but is highly useful.

一般的解决方案是在 Cargo.toml 中手动限制您的 Serde 版本以匹配其余的依赖项:

The general solution is to manually restrict your version of Serde in your Cargo.toml to match the rest of the dependencies:

serde = "0.9"
serde_derive = "0.9"
serde_json = "0.9"

这可能并不总是可行,在这种情况下,您可能需要追捕 crate 所有者以升级他们的依赖项.

This may not always be possible, in which case you may need to hound the crate owners to upgrade their dependencies.

[dependencies]
chrono = "0.3.0"
rocket = "0.2.8"
rocket_codegen = "0.2.8"
serde = "1.0.8"
serde_derive = "1.0.8"
serde_json = "1.0.2"
mysql = "11.1.2"
diesel = { version = "0.13.0", features = ["mysql","chrono"] }
diesel_codegen = { version = "0.13.0", features = ["mysql"] }
dotenv = "0.10.0"

[dependencies.rocket_contrib]
version = "*"
default-features = false
features = ["handlebars_templates"]

rocket_contrib 0.2.8 依赖于 Serde 0.9,但你已经引入了 Serde 1.0.这个来自 cargo tree 的删节片段显示了这个问题:

rocket_contrib 0.2.8 depends on Serde 0.9, but you have pulled in Serde 1.0. This abridged snippet from cargo tree shows the problem:

reproduction v0.1.0 (file:///private/tmp/reproduction)
├── rocket_contrib v0.2.8
│   ├── handlebars v0.25.3
│   │   └── serde_json v0.9.10
│   │       └── serde v0.9.15
│   ├── serde v0.9.15 (*)
│   └── serde_json v0.9.10 (*)
├── serde v1.0.8 (*)
├── serde_derive v1.0.8
│   ├── serde_derive_internals v0.15.1
└── serde_json v1.0.2 (*)

即将发布的 0.3 版 应该允许使用 Serde 1.0.

The upcoming version 0.3 of Rocket should allow using Serde 1.0.

[dependencies]
bodyparser = "0.5"
bson = "0.8"
iron = "0.5"
jwt = "0.4"
mongodb = "0.3"
router = "0.5"
rust-crypto = "0.2"
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
time = "0.1"

bodyparser 0.5 依赖 Serde 0.8,MongoDB 拉入 0.9,但 crate 和 BSON 拉入 Serde 1.0.这个来自 cargo tree 的删节片段显示了这个问题:

bodyparser 0.5 depends on Serde 0.8, MongoDB has pulled in 0.9, but the crate and BSON have pulled in Serde 1.0. This abridged snippet from cargo tree shows the problem:

reproduction v0.1.0 (file:///private/tmp/reproduction)
├── bodyparser v0.5.0
│   ├── serde v0.8.23
│   └── serde_json v0.8.6
│       └── serde v0.8.23 (*)
├── bson v0.8.0
│   ├── serde v1.0.8
│   ├── serde_json v1.0.2
│   │   └── serde v1.0.8 (*)
├── mongodb v0.3.0
│   ├── textnonce v0.6.0
│   │   ├── serde v0.9.15
│   │   └── serde_derive v0.9.15
├── serde v1.0.8 (*)
├── serde_derive v1.0.8
├── serde_json v1.0.2 (*)

Bodyparser 0.7.0 应支持 Serde 1.0.textnonce 的状态 不太清楚,但这种依赖性可能是私有的 一个,所以在这种情况下可能无关紧要.

Bodyparser 0.7.0 should support Serde 1.0. The state of textnonce is less clear, but that dependency might be a private one, so it might not matter in this case.

chrono = "0.4.0"
diesel = { version = "0.13.0", features = [ "chrono", "sqlite" ] }
diesel_codegen = { version = "0.13.0", features = [ "sqlite" ] }
dotenv = "0.9.0"

Chrono 当前版本是 0.4.0,但 Diesel 只知道如何序列化 Chrono 0.3.0.

The current version of Chrono is 0.4.0, but Diesel only knows how to serialize Chrono 0.3.0.

reproduction v0.1.0 (file:///private/tmp/reproduction)
├── chrono v0.4.0
├── diesel v0.13.0
│   ├── chrono v0.3.0

河豚/分组密码特征

[dependencies]
blowfish = "0.2.1"
block-cipher-trait = "0.3.0"

reproduction v0.1.0 (file:///private/tmp/reproduction)
├── block-cipher-trait v0.3.0
│── blowfish v0.2.1
    ├── block-cipher-trait v0.2.0

连杆/活塞2d-graphics

[dependencies]
piston_window = "0.74.0"
conrod = { version = "0.56.0", features = ["piston"] }

repro v0.1.0 (file:///private/tmp/repro)
├── conrod v0.56.0
│   ├── piston2d-graphics v0.23.0
└── piston_window v0.74.0
    ├── piston2d-graphics v0.24.0 (*)

actix/期货

[dependencies]
actix-web = "0.6.10"
futures = "0.2.1"

repro v0.1.0 (file:///private/tmp/repro)
├── actix-web v0.6.12
│   ├── actix v0.5.8
│   │   ├── futures v0.1.21
└── futures v0.2.1

美好的未来?

RFC 1977 提议引入 public 的概念em> 和 private 对 Cargo 的依赖.如果您使用的 crate 反过来公开暴露另一个 crate 的类型,Cargo 将确保您为具有通用类型的 crate 使用单个统一版本.

A bright future?

RFC 1977 proposes to introduce the notion of public and private dependencies to Cargo. If you use a crate that in turn publicly exposes another crate's types, Cargo would ensure that you use a single unified version for the crate with the common types.

这篇关于为什么 trait 没有为明确实现的类型实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆