你如何从图书馆中制作一个不可浏览,类似C的枚举?

时间:2016-02-01 21:45:51

标签: hash enums hashmap rust

我正在学习如何通过在SFML(使用RSFML)中制作一个Pac-Man克隆游戏来使用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>
}

但是仍然存在这个错误,因为我假设它只是混合了结构中每个属性的hashable trait。

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 trait实现添加到我创建的新HKey结构中,但我不知道如何从枚举中生成哈希,因为它似乎把它变成一个int并不容易。理想情况下,如果Rust允许,我希望安全地做到这一点。有没有人对如何做到这一点有任何建议?

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

1 个答案:

答案 0 :(得分:1)

Key枚举是一个类似C的枚举(即没有变体有附加数据),因此我们可以使用as将此类型的枚举转换为整数,例如u32。然后,我们可以推迟u32 Hash的实施。

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

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并通过将枚举转换为Hash,然后使用u32的{​​{1}}实现来实现u32