Rust 中作为 class 成员的异构集合

Heterogeneous collection as a member of a class in Rust

我是 Rust 新手,对生命周期不是很了解,所以可能这就是我无法解决以下问题的原因。我需要一个解决方案,其中 class 具有异构 HashMap,其中包含从相同特征派生的不同对象。

我必须能够动态地扩展具有某些(多个)功能的对象。也欢迎其他解决方案。在编译时向 class 添加功能也可以,但直接向主 class 添加功能则不行。

use std::collections::HashMap;

trait DoerTrait {
    fn do_something( & self, a : u8, b : u8 ) -> u8;
}

struct MyDoer<'a> {
}

impl DoerTrait for MyDoer<'a> {
    fn do_something( & self, a : u8, b : u8 ) -> u8 {
        return a + b;
    }
}

struct MyMain<'a> {
    doers : HashMap<u8,&'a dyn DoerTrait>,
}

impl<'a> MyMain<'a> {
    fn new() -> Self {
        Self {
            doers : HashMap::new()
        }
    }

    fn add_doer( &mut self, id : u8, doer : & dyn DoerTrait ) {
        self.doers.insert( id, doer );
    }

    fn do_something( & self, id : u8 ) {
        match self.doers.get( &id ) {
            Some( doer ) => {
                println!( "{}", doer(19,26) );
            }
            None => {
                println!( "Doer not specified!" );
            }
        }
    }
}

fn main() {
    let mut mymain = MyMain::new();
    let mydoer = MyDoer{};
    mymain.add_doer( 42, &mydoer );
    mymain.do_something( 42 );
}

不太确定你有什么问题,一旦 MyDoer 被剥夺了它不正确的(不必要的)生命周期并且在 impl MyMain 上正确声明了生命周期,编译器直接指向参数add_doer 不匹配(之后它指出 do_something 中的 doer 不是函数):

use std::collections::HashMap;

trait DoerTrait {
    fn do_something(&self, a: u8, b: u8) -> u8;
}

struct MyDoer;

impl DoerTrait for MyDoer {
    fn do_something(&self, a: u8, b: u8) -> u8 {
        return a + b;
    }
}

struct MyMain<'a> {
    doers: HashMap<u8, &'a dyn DoerTrait>,
}

impl<'a> MyMain<'a> {
    fn new() -> Self {
        Self {
            doers: HashMap::new(),
        }
    }

    fn add_doer(&mut self, id: u8, doer: &'a dyn DoerTrait) {
        self.doers.insert(id, doer);
    }

    fn do_something(&self, id: u8) {
        match self.doers.get(&id) {
            Some(doer) => {
                println!("{}", doer.do_something(19, 26));
            }
            None => {
                println!("Doer not specified!");
            }
        }
    }
}

fn main() {
    let mut mymain = MyMain::new();
    let mydoer = MyDoer {};
    mymain.add_doer(42, &mydoer);
    mymain.do_something(42);
}