无法在 hashmap 中指定关联类型值?

问题描述

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

解决方法

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

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

不过,整个事情看起来是从 Java 或 C# 中提取出来的,这预示着它的实际工作并不好。 Rust 是一种相当不同的语言,它对语言用户有自己的一套限制。尝试在其中复制 Java 设计通常会导致沮丧,并且无法正常工作。

,
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))
    }
}