Я пытаюсь реализовать фабричный метод, который возвращает 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
.
Завод выглядит так (не compile):
fn factory<Q: QType>(name: &str) -> Box<dyn Service<Query = Q>> {
match name {
"amazon" => Box::new(amzn::Amazon {}),
other => panic!("Invalid service {}", other),
}
}
Теперь у меня есть только один сервис, и я мог бы указать c в типе Parameters в сигнатуре - что сделает его компиляцией - но я хочу иметь обобщенный c фабричный метод и добавление дополнительных служб.
Вот реализация службы 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> {}
}
}
Компилятор говорит:
error[E0271]: type mismatch resolving `::Query == Q`
--> src/main.rs:9:21
|
9 | "amazon" => Box::new(amzn::Amazon {}),
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found struct `amzn::Product`
|
= note: expected type `Q`
found type `amzn::Product`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
= note: required for the cast to the object type `dyn Service`
На основе это сообщение об ошибке, я не уверен, как указать параметр типа. Я попытался извлечь создание Amazon
и дать ему явные параметры типа, но это просто оставляет различные ошибки. Кроме того, следование связанной главе 10.02 в книге не дает никаких объяснений по случаю со связанными типами. Наконец, я также попробовал маршрут RF C -1598: Generi c Associated Types , но я не смог ни его скомпилировать, ни уверен, действительно ли он мне нужен.
Также обратите внимание, что я добавил оболочку Box
и ограничение QType
, основанные на других ответах здесь на SO по аналогичным вопросам, но я мог бы быть совершенно неверным путем здесь.
Любая помощь очень ценится.