在使用使用&'static str作为键类型的HashMap时,我创建了一个newtype来按指针而不是按字符串内容进行散列,以减少开销.

pub struct StaticStr(&'static str);

impl Hash for StaticStr {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.as_ptr().hash(state)
    }
}

impl PartialEq for StaticStr {
    fn eq(&self, other: &Self) -> bool {
        self.0.as_ptr() == other.0.as_ptr()
    }
}

impl Eq for StaticStr {}

事实证明,这并不是始终如一的工作,如以下示例所示.

pub type MyMap = HashMap<StaticStr, u8>;
pub const A: &str = "A";

pub fn make_map() -> MyMap {
    let mut map = MyMap::new();
    map.insert(StaticStr(A), 1);
    map
}

pub fn get_value(control: &MyMap) -> Option<u8> {
    control.get(&StaticStr(A)).cloned()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    pub fn map_made_in_lib() {
        let map = make_map();
        assert_eq!(get_value(&map), Some(1));
    }

    #[test]
    pub fn map_made_in_test() {
        // Same as make_map()
        let mut map = MyMap::new();
        map.insert(StaticStr(A), 1);

        // This check fails
        assert_eq!(get_value(&map), Some(1));
    }
}

注意,在第一个测试中,字符串常数A仅直接用于lib crate .在第二次测试中,A直接用于lib crate 和测试 crate .我发现,尽管两个测试使用相同的字符串常量,但指针是不同的,这取决于哪个 crate 按名称引用字符串常量.这在我创建的minimal reproduction个例子中得到了证明.我原本希望字符串文字对于定义它的 crate 只包含一次,或者至少链接器足够智能,能够消除字符串文字的重复.这种行为有什么原因吗?

推荐答案

static代替const

常量项是一个可选命名的常量值,它不是

A static item is similar to a constant, except that it represents a precise memory location in the program. All references to the static refer to the same memory location.个静态项具有静态

Rust相关问答推荐

常量泛型和类型枚举箱有重叠的用途吗?

返回的future 不是`发送`

integer cast as pointer是什么意思

使用Box优化可选的已知长度数组的内存分配

如何在递归数据 struct 中移动所有权时变异引用?

从未排序的链表中删除重复项的铁 rust 代码在ELSE分支的低级上做了什么?

在Rust中克隆源自INTO_ITER()的迭代器的成本?

如何对一个特征的两个实现进行单元测试?

当我try 使用 SKI 演算中的S I I实现递归时,为什么 Rust 会失败?

`use` 和 `crate` 关键字在 Rust 项目中效果不佳

如何保存指向持有引用数据的指针?

为什么Rust中无法推断生命周期?

Rust 打包在 .deb 中

我如何取消转义,在 Rust 中多次转义的字符串?

返回迭代器的特征

从函数返回 u32 的数组/切片

将文件的第一行分别读取到文件的其余部分的最有效方法是什么?

当特征函数依赖于为 Self 实现的通用标记特征时实现通用包装器

提取 struct 生成宏中字段出现的索引

为什么 Bevy 的 Trait 边界不满足 Rapier 物理插件?