rust - 如何存储实现共同特征的结构(不是实例)?

标签 rust

背景

我有一个特征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/

相关文章:

http - 如何在 Rust 中使用媒体文件正确格式化 HTTP 响应

rust - 如果类型没有实现复制,我如何将具体类型与选项的Option进行比较?

rust - 是否可以有条件地启用 `derive` 之类的属性?

rust - 如何实现 future 功能的流

rust - 我得到的特征绑定(bind) `T: sns_pub::_IMPL_DESERIALIZE_FOR_Message::_serde::Serialize` 不满意

rust - 为什么 Rust 允许返回类型错误的代码,但只允许尾随分号?

rust - 如何获得与Rust HashMap的最大值关联的 key ?

rust - 将 Ref::map 与特征对象一起使用时无法推断生命周期

arrays - 有没有办法不必两次初始化数组?

rust - `?` 不能 't convert the error to ` std::io::Error`