簡體   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