【问题标题】:How do you make a non-hashable, C-like enum from a library hashable?你如何从一个可散列的库中制作一个不可散列的、类似 C 的枚举?
【发布时间】:2016-05-10 12:28:24
【问题描述】:

我正在通过在 SFML 中制作一个小 Pac-Man 克隆游戏(使用 RSFML)来学习如何使用 Rust,但是我在映射 Key 枚举时遇到了问题。

我已经创建了这个结构,它具有与布尔值相关的键映射,我在以前的 C++ 项目中使用过它,所以我只是想复制它。

use sfml::window::keyboard::Key;
use std::collections::HashMap;

pub struct Input {
    held_keys: HashMap<Key, bool>,
    pressed_keys: HashMap<Key, bool>,
    released_keys: HashMap<Key, bool>
}

然后我收到一个关于 Key 不可散列的错误。我检查了库,枚举没有派生 Hash 以使其可用作密钥。我四处寻找有关此的建议,但没有得到很多答案;有人建议尝试将枚举包装在一个新的结构类型中并从那里派生Hash

所以我尝试添加以下内容:

#[derive(Hash, Eq, PartialEq)]
struct HKey {
     key: Key
}

pub struct Input {
    held_keys: HashMap<HKey, bool>,
    pressed_keys: HashMap<HKey, bool>,
    released_keys: HashMap<HKey, bool>
}

但这仍然以这个错误告终,因为我假设它所做的只是混合结构中每个属性的可哈希特征。

the trait `core::hash::Hash` is not implemented for the type `sfml::window::keyboard::Key`
    key: Key
    ^~~~~~~~
in this expansion of #[derive_Hash] (defined in src/input.rs)
help: run `rustc --explain E0277` to see a detailed explanation
note: required by `core::hash::Hash::hash`

我现在猜测我需要尝试手动将 Hash 特征实现添加到我创建的新 HKey 结构中,但我不知道如何从枚举生成哈希,因为它似乎不是很容易把它变成一个int。如果 Rust 允许的话,我理想地希望安全地做到这一点。有人对如何做到这一点有任何建议吗?

I am uploading my progress to GitHub, if you need a bigger picture.

【问题讨论】:

    标签: hash enums hashmap rust


    【解决方案1】:

    Key 枚举是一个类似 C 的枚举(即没有变体有额外的数据),所以我们可以使用 as 将这种类型的枚举转换为整数,例如u32。然后,我们可以按照u32Hash 的实现。

    这是一个不使用外部库的最小示例:

    use std::hash::{Hash, Hasher};
    
    #[derive(Copy, Clone)]
    enum E {
        A, B, C
    }
    
    struct NE(E);
    
    impl Hash for NE {
        fn hash<H>(&self, state: &mut H) where H: Hasher {
            (self.0 as u32).hash(state)
        }
    }
    

    E 没有实现HashNE 包装了一个E 并通过将枚举转换为u32 来实现Hash,然后使用u32Hash 实现。

    【讨论】:

    • @Shepmaster 然后你哭了。
    • 谢谢弗朗西斯。我不知道你可以用'as'转换一个枚举。我设法将它实现到我的代码中,没有任何问题。
    猜你喜欢
    • 1970-01-01
    • 2017-04-09
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 2013-07-08
    • 2016-12-27
    相关资源
    最近更新 更多