繁体   English   中英

Rust结构不能替换HashMap中的trait

[英]Rust struct can't replace trait in HashMap

我正在尝试创建一个包含特定输入的已知值的HashMap 此输入可以接受多种类型,只要它们实现某种特征即可。 但是,在这种情况下,只给出了某种类型,Rust不喜欢这种类型。

有没有办法将结构“转换”为特征,或以其他方式解决这个问题?

#![allow(unused)]

use std::collections::HashMap;
use std::hash::*;


trait Element: Eq + PartialEq + Hash {}

trait Reaction<T: Element> {}


#[derive(Eq, Hash, PartialEq)]
struct Ion {
    charge: u16
}

impl Element for Ion {}


#[derive(Eq, Hash, PartialEq)]
struct RedoxReaction<T: Element> { left: T }

impl<T: Element> Reaction<T> for RedoxReaction<T> {}


fn get_sep_database<T: Element>() -> HashMap<RedoxReaction<T>, f32> {
    let mut map: HashMap<RedoxReaction<T>, f32> = HashMap::new();

    let reaction = RedoxReaction {
        left: Ion {
            charge: 1
        }
    };

    // note: expected type `RedoxReaction<T>`
    //       found type `RedoxReaction<Ion>`
    map.insert(reaction, 0.000 as f32);

    return map;
}


fn main() {
    let db = get_sep_database();

    let reaction = RedoxReaction {
        left: Ion {
            charge: 1
        }
    };

    // expected this to be 0.000
    let sep = db.get(&reaction);
}

这个问题的标准解决方案是使用特征对象而不是泛型。 具体来说, RedoxReaction将定义为:

#[derive(Eq, Hash, PartialEq)]
struct RedoxReaction { left: Box<Element> }

但是,这在这里PartialEq ,因为PartialEqEqHash都不是对象安全的 实际上,当其中一个是Ion而另一个是Photon时,询问两个Elements是否相等并没有多大意义。

我建议您考虑为元素使用枚举 所有元素都具有相同的类型(枚举Element ),对象安全性不会成为问题。

我最终通过使用Reaction哈希作为HashMap的键来解决这个问题,具有以下功能:

use std::collections::hash_map::DefaultHasher;
use std::hash::*;

fn reaction_to_hash<E: Element>(reaction: &Reaction<E>) -> u64 {
    let mut s = DefaultHasher::new();
    reaction.hash(&mut s);
    s.finish()
}

然后您可以使用map.insert(reaction_to_hash(&reaction), <value>)来存储值,并使用map.get(& reaction_to_hash(&reaction))来检索值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM