背景
我有一个特征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()
不需要通过设计实例,因此为什么需要实例化它?
最佳答案
如果要将名称映射到 Action ,则最有可能使用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");
}
(Playground Link)
关于rust - 如何存储实现共同特征的结构(不是实例)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60312249/