【问题标题】:Can't specify associate type value in hashmap?无法在 hashmap 中指定关联类型值?
【发布时间】:2021-09-21 07:20:22
【问题描述】:
pub trait Observer{
    type DataType;
    fn new(action: fn(&mut Self::DataType))->Self;
    fn update(&self, data:&mut Self::DataType);
}

pub trait Subject{
    type ObserverType: Observer;
    fn new()-> Self;
    fn add_observer(&mut self,observer:Rc<Self::ObserverType>);
    fn remove_observer(&mut self,observer:&Rc<Self::ObserverType>);
    fn data(&mut self)-> &<<Self as Subject>::ObserverType as Observer>::DataType;
    fn notification(&mut self);
}

pub struct SubjectMgr{
}

impl SubjectMgr {
    fn new(){
        let mut map = HashMap::new();
        map.insert("PlayerList",PlayerListSubject::new());
        map.insert("MonsterList",MonsterListSubject::new());
    }
}

尝试使用具有关联值的哈希映射作为成员。但是我不能有一个 hashmap 值类型吗?

文件结构如下: enter image description here

【问题讨论】:

    标签: dictionary generics rust hashmap associate


    【解决方案1】:

    在大多数 Rust 集合中,值(和键)必须具有相同的类型PlayerListSubjectMonsterListSubject 是不同的类型,因此它们的值不能放入同一个映射中,除非您在 trait objects 后面键入擦除它们(假设特征是对象安全的,我认为这不是案例在这里)。

    将来,您可能希望提供问题的minimal reproducible examples,而不是不完整的不可用代码。这使得潜在帮助者更容易尝试和理解这个问题,确保没有人在误解上浪费时间,并增加获得有用答案的几率(我不确定这个答案是否)。

    不过,整个东西看起来是从 Java 或 C# 中提取出来的,这预示着它实际上工作得不好。 Rust 是一种完全不同的语言,它对语言用户设置了自己的一组限制。尝试在其中复制 Java 设计通常会导致挫败感并且无法正常工作。

    【讨论】:

    • 感谢您的友好建议。我试试写成可执行代码再上传!
    【解决方案2】:
    use std::{ops::Deref, rc::Rc};
    use super::{Observer, Subject};
    
    struct Monster{
        id: String,
        password: String,
    }
    
    #[derive(Default)]
    struct MonsterList{
        players: Vec<Monster>
    }
    
    impl Deref for MonsterList {
        type Target = Vec<Monster>;
    
        fn deref(&self) -> &Self::Target {
            &self.players
        }
    }
    
    impl MonsterList {
        pub fn new() -> Self {
            MonsterList::default()
        }
    }
    
    pub struct MonsterListObserver{
        action: fn(&mut MonsterList),
    }
    
    impl Observer for MonsterListObserver{
        type DataType = MonsterList;
    
        fn new(action: fn(&mut Self::DataType))->Self {
            Self {action}
        }
    
        fn update(&self, data:&mut Self::DataType) {
            (self.action)(data);
        }
    }
    
    pub struct MonsterListSubject{
        monster_list: MonsterList,
        observers: Vec<Rc<MonsterListObserver>>,
    }
    
    impl Subject for MonsterListSubject{
        type ObserverType = MonsterListObserver;
    
        fn new()-> Self {
            Self {
                monster_list: MonsterList::new(),
                observers: Vec::new(),
            }
        }
    
        fn add_observer(&mut self,observer:Rc<Self::ObserverType>) {
            self.observers.push(observer);
        }
    
        fn remove_observer(&mut self,remove_observer:&Rc<Self::ObserverType>) {
            self.observers.retain(|observer|{
                let observer = &**observer as *const MonsterListObserver;
                let remove_observer = &**remove_observer as *const MonsterListObserver;
                observer != remove_observer
            })
        }
    
        fn data(&mut self)-> &<Self::ObserverType as Observer>::DataType {
            &mut self.monster_list
        }
    
        fn notification(&mut self) {
            let monster_list = &mut self.monster_list;
            self.observers
                .iter()
                .for_each(|observer| observer.update(monster_list))
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2017-03-17
      • 1970-01-01
      相关资源
      最近更新 更多