gpt4 book ai didi

rust - "the method cannot be invoked on a trait object"在单独的特征实现上

转载 作者:行者123 更新时间:2023-11-29 08:15:29 34 4
gpt4 key购买 nike

我在使用单独的特征实现时遇到错误“无法在特征对象上调用该方法”。

这是我的最小可重现示例:

Cargo.toml

[package]
name = "mrp"
version = "0.1.0"
authors = ["Empty2k12"]
edition = "2018"

[dependencies]
futures = "0.1.27"
tokio = "0.1.20"
serde = { version = "1.0.92", features = ["derive"] }
serde_json = { version = "1.0" }

ma​​in.rs

use serde::{Deserialize, Serialize};

pub mod integrations {
pub mod serde_integration;
}

struct MyDbClient {}

#[derive(Serialize, Deserialize, Debug)]
pub struct Weather {
temperature: i32,
}

#[cfg(test)]
mod tests {
use super::Weather;
use super::MyDbClient;
use crate::integrations::serde_integration::MyDbSerdeORM;

#[test]
fn mrp() {
let weather = Weather { temperature: 82 };

MyDbClient {}.json_query::<Weather, ToString>(serde_json::to_string(&weather).unwrap())
}
}

integrations/serde_integration.rs

use serde::de::DeserializeOwned;

use super::super::MyDbClient;

use futures::Future;

pub trait MyDbSerdeORM {
fn json_query<T: 'static, Q>(self, q: Q) -> Box<dyn Future<Item = Option<T>, Error = ()>>
where
Q: ToString,
T: DeserializeOwned;
}

impl MyDbSerdeORM for MyDbClient {
fn json_query<T: 'static, Q>(self, q: Q) -> Box<dyn Future<Item = Option<T>, Error = ()>>
where
Q: ToString,
T: DeserializeOwned,
{
Box::new(futures::future::ok(Some(
serde_json::from_str(&q.to_string()).unwrap(),
)))
}
}
error: the `json_query` method cannot be invoked on a trait object
--> src/main.rs:27:23
|
27 | MyDbClient {}.json_query::<Weather, ToString>(serde_json::to_string(&weather).unwrap())
| ^^^^^^^^^^
|
= note: another candidate was found in the following trait, perhaps add a `use` for it:
`use crate::integrations::serde_integration::MyDbSerdeORM;`

该错误也无济于事,因为它建议添加一个已经存在的导入。

如何修复我的 MRE 中存在的错误?如何以更好、更质朴的方式实现?

最佳答案

有一个简单的方法可以解决您的问题:由于您已经在自己的箱子中定义了 MyDbClient 结构,因此您可以简单地实现您想要的方法而无需指定另一个特点。这将适用于您的原始示例:

use futures::Future;
use serde::{de::DeserializeOwned, Deserialize, Serialize};

pub struct MyDbClient {
pub url: String,
}

#[cfg(feature = "serde-orm")]
impl MyDbClient {
pub fn json_query<T: 'static, Q>(self, q: Q) -> Box<dyn Future<Item = Option<T>, Error = ()>>
where
Q: ToString,
T: DeserializeOwned,
{
Box::new(futures::future::ok(Some(
serde_json::from_str(&q.to_string()).unwrap(),
)))
}
}

#[cfg_attr(feature = "serde-orm", derive(Serialize, Deserialize, Debug))]
pub struct Weather {
temperature: i32,
}

#[cfg(test)]
#[cfg(feature = "serde-orm")]
mod tests {
use super::*;

#[test]
fn mrp() {
let weather = Weather { temperature: 82 };

let client: MyDbClient = MyDbClient {
url: "localhost".to_owned(),
};

client.json_query::<Weather, _>(serde_json::to_string(&weather).unwrap());
}
}

但这有一个缺点,因为您不能将实现重用于 MyDbClient 以外的类型。虽然这并不适用于所有人,但这可能适合您的用例。

关于rust - "the method cannot be invoked on a trait object"在单独的特征实现上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56448638/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com