Я хочу иметь возможность хранить несколько фабрик в одной хэш-карте, чтобы позже добавить их в нее (например, с помощью плагинов), а затем получить каждую из них по ключу в приложении (это менеджер ресурсов).
Проблема заключается в общем свойстве «Ткань», ткани могут создавать плоды разных типов, но мне нужно указать здесь что-то HashMap<String, Box<dyn Fabric>>
, например HashMap<String, Box<Fabric<Apple>>>
или HashMap<String, Box<Fabric<T>>>
, что также не очень полезно, посколькуЯ сказал, что мы можем создавать действительно разные фрукты.
Также я думаю, что в методе foo может возникнуть проблема с заимствованием контента.
Так как бы вы реализовали этот «путь ржавчины»?
use std::collections::HashMap;
trait Fruit {
fn get_name(&self) -> String;
}
trait Fabric<T: Fruit> {
fn build(&self) -> Box<T>;
}
struct Banana {}
impl Fruit for Banana {
fn get_name(&self) -> String { String::from("I'm banana") }
}
struct BananaFabric {}
impl Fabric<Banana> for BananaFabric {
fn build(&self) -> Box<Banana> {
Box::new(Banana {})
}
}
struct Apple {}
impl Fruit for Apple {
fn get_name(&self) -> String { String::from("I'm apple") }
}
struct AppleFabric {}
impl Fabric<Apple> for AppleFabric {
fn build(&self) -> Box<Apple> {
Box::new(Apple {})
}
}
struct C {
map: HashMap<String, Box<dyn Fabric>>,
}
impl C {
pub fn new() -> C {
C {
map: HashMap::new()
}
}
pub fn foo(&self, key: String) {
match self.map.get(&key) {
Some(&fabric) => {
let fruit = fabric.build();
println!("{}", fruit.get_name())
},
_ => println!("No fabric found")
}
}
}
fn main() {
let c = C::new();
c.foo(String::from("bar"));
}