gpt4 book ai didi

rust - 具有关联类型的工厂方法

转载 作者:行者123 更新时间:2023-12-03 11:23:52 24 4
gpt4 key购买 nike

我正在尝试实现一个返回 Service 的工厂方法。具有关联的类型。我让它在没有关联类型的情况下工作,但是一旦我添加它,无论我如何按摩它,我都无法编译它..

这是Service :

trait QType {}

trait Service {
type Query: QType;

fn sanitize(&self, query: &str) -> Result<Self::Query, String>;

fn run(&self, query: &Self::Query) -> Result<(), String>;
}

所以这个想法是 sanitize函数返回 Query 的一个实例, 然后可以传递给 run功能。

工厂看起来像这样(不编译):

fn factory<Q: QType>(name: &str) -> Box<dyn Service<Query = Q>> {
match name {
"amazon" => Box::new(amzn::Amazon {}),
other => panic!("Invalid service {}", other),
}
}

现在我这里只有一个服务,我可以在签名中指定类型参数——这将使它编译——但我​​想要一个通用工厂方法并添加更多服务。

这是 Amazon 的实现服务:

mod amzn {
use super::*;

pub struct Amazon {}

pub struct Product {
name: String,
}

impl QType for Product {}

impl Service for Amazon {
type Query = Product;
fn sanitize(&self, query: &str) -> Result<Product, String> {}
fn run(&self, query: &Product) -> Result<(), String> {}
}
}

编译器说:

错误[E0271]:类型不匹配解析`::Query == Q`
--> src/main.rs:9:21
|
9 | “亚马逊” => Box::new(amzn::Amazon {}),
| ^^^^^^^^^^^^^^^^^^^^^^^^^ 预期类型参数,找到 struct `amzn::Product`
|
=注意:预期类型`Q`
找到类型`amzn::Product`
= help: 类型参数必须被约束以匹配其他类型
= 注意:有关更多信息,请访问 https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
= 注意:强制转换为对象类型 `dyn Service` 是必需的

基于此错误消息,我不确定如何指定类型参数。我已经尝试提取 Amazon 的创建并给它显式类型参数,但这只会留下不同的错误。此外,在本书中链接的第 10.02 章之后,并没有对关联类型的案例进行任何解释。最后,我也尝试了 RFC-1598: Generic Associated Types的路线,但我既不能编译它,也不能确定我是否真的需要它。

另请注意,我添加了 Box包装和 QType基于类似问题的其他答案的限制,但我可能完全走错了路..

任何帮助深表感谢。

最佳答案

此签名无法实现:

fn factory<Q: QType>(name: &str) -> Box<dyn Service<Query = Q>>

关联类型始终由实现类型唯一确定。 IE。 Service 的每个实现只选择一种关联类型 Query .

这与 factory 不一致。 ,这让调用者决定关联的类型应该是什么。应该清楚地看到,如果您调用 factoryQ那不是 Product然后是 match里面的代码表达式不再类型检查。

您可以通过修复 Query 的选择来完成这项工作。 :
fn factory(name: &str) -> Box<dyn Service<Query = Product>> {
match name {
"amazon" => Box::new(amzn::Amazon {}),
other => panic!("Invalid service {}", other),
}
}

如果您希望调用者选择类型,那么您需要找到一种方法,以便函数体适用于 Q 的任何选择。 .例如,您可以将构造与 QType 关联起来。特征:
trait QType {
fn create_service(name: &str) -> Option<Box<dyn Service<Query = Self>>>;
}

fn factory<Q: QType>(name: &str) -> Box<dyn Service<Query = Q>> {
Q::create_service(name).expect("Invalid service")
}

并为您的类型实现:
impl QType for Product {
fn create_service(name: &str) -> Option<Box<dyn Service<Query = Self>>> {
match name {
"amazon" => Some(Box::new(amzn::Amazon {})),
other => None,
}
}
}

关于rust - 具有关联类型的工厂方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59929231/

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