我有一个特征MyTrait
:
trait MyTrait {
fn name() -> String;
fn foo();
}
name
定义了它的名称,foo
是它的associated function,为我做了一些工作。
我有许多实现此特征的结构,我想定义一个函数
fn do_work(name: &String);
查找结构TheStruct
,其中TheStruct::name()
是name
,并调用TheStruct::foo()
。
要实现我的目标,我需要一个HashMap
或使用match
,但是目标值应该是实现MyTrait
的结构(不是实例),但这似乎是不可能的。>
将name()
和foo()
更改为struct方法,即name(&self)
和foo(&self)
,然后使用HashMap
或仅使用match
来获取内容对。但是我认为,由于name()
和foo()
不需要通过设计实例,因此为什么需要实例化它?
答案 0 :(得分:1)
如果要将名称映射到操作,则最有可能使用HashMap<String, fn()>
的做法是最有意义的。例如:
use std::collections::{HashMap, hash_map::Entry};
trait MyTrait {
fn name() -> String;
fn foo();
}
struct Example;
impl MyTrait for Example {
fn name() -> String {
"Example".to_string()
}
fn foo() {
println!("Do Example");
}
}
#[derive(Default)]
struct Worker {
handlers: HashMap<String, fn()>,
}
impl Worker {
fn new() -> Self {
Default::default()
}
fn register_handler<T: MyTrait>(&mut self) {
let name = T::name();
match self.handlers.entry(name) {
Entry::Occupied(_) => panic!("handler already registered"),
entry => {entry.or_insert(T::foo);},
}
}
fn do_work(&self, name: &str) {
let handler = self.handlers.get(name).expect("unknown handler");
handler();
}
}
fn main() {
let mut worker = Worker::new();
worker.register_handler::<Example>();
worker.do_work("Example");
}