在不同集合中使用 String 及其指针的安全有效方法 [英] Safe and efficient way to use String and its pointer in different collections
问题描述
- 我有一堆不可变的长字符串,我想将它们存储在
HashSet
中. - 我需要一堆以这些字符串为键的映射.
- 我想使用对这些字符串的引用作为这些映射中的键,以避免复制字符串.
这就是我最终达到这种状态的方式.唯一需要担心的是我需要在第 5 行制作这个额外的副本.
This is how I managed to eventually get to this status. The only concern is this extra copy I need to make at line 5.
let mut strings: HashSet<String> = HashSet::new(); // 1
let mut map: HashMap<&String, u8> = HashMap::new(); // 2
// 3
let s = "very long string".to_string(); // 4
strings.insert(s.clone()); // 5
let s_ref = strings.get(&s).unwrap(); // 6
map.insert(s_ref, 5); // 7
为了避免这种克隆,我找到了两种解决方法:
To avoid this cloning I found two workarounds:
- Use
Rc
for string (adds overhead and code clutter) - Use unsafe code
是否有任何明智的方法可以消除这种过度克隆?
Is there any sensible way to remove this excessive cloning?
推荐答案
在我看来,您正在寻找的是字符串实习.有一个库,string-cache,它是作为 Servo 项目的一部分开发的,它可能是的帮助.
It seems to me that what you are looking for is String Interning. There is a library, string-cache, which was developed as part of the Servo project which may be of help.
无论如何,基础很简单:
In any case, the basics are simple:
- 一个长期存在的
String
池,保证它们根本不会移动 - 避免在池中插入重复项的查找系统
- a long-lived pool of
String
, which guarantees they will not be moving at all - a look-up system to avoid inserting duplicates in the pool
您可以使用 typed arena 来存储您的 String
,然后将 &str
存储到这些字符串中而不复制它们(只要 arena 存在,它们就会存在).在顶部使用 HashSet<&str>
以避免重复,您就设置好了.
You can use a typed arena to store your String
, and then store &str
to those strings without copying them (they will live for as long as the arena lives). Use a HashSet<&str>
on top to avoid duplicates, and you're set.
这篇关于在不同集合中使用 String 及其指针的安全有效方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!