如何在将密钥插入HashMap后保留对密钥的引用?

时间:2015-09-04 15:39:34

标签: rust

我想插入一个HashMap,但保持一个不可变的借用密钥传递给地方。在我的情况下,键是字符串。

这是一种方式:

use std::collections::HashMap;
let mut map = HashMap::new();
let id = "data".to_string();  // This needs to be a String
let cloned = id.clone();

map.insert(id, 5);

let one = map.get(&cloned);
let two = map.get("data");
println!("{:?}", (one, two));

但这需要克隆。

这个工作直到Rust 1.2.0:

use std::collections::HashMap;
use std::rc::Rc;
use std::string::as_string;

let mut map = HashMap::new();
let data = Rc::new("data".to_string()); // This needs to be a String
let copy = data.clone();
map.insert(data, 5);

let one = map.get(&copy);
let two = map.get(&*as_string("data"));
println!("{:?}", (one, two));

如何使用Rust 1.2.0实现此目的?

理想情况下,我希望将一个键放入HashMap,但保留对它的引用,并允许我使用&str类型访问其中的元素,而无需额外分配。

1 个答案:

答案 0 :(得分:9)

简短的回答是,你不能。当您在HashMap中插入内容时,转移所有权。这样做会使您对密钥的任何引用无效,因为密钥已移动到地图分配的内存中。

RFC 1194 (Set Recovery)提出了一种方法来获取HashSet(不是地图)存储的密钥的引用。需要进一步的信息和研究来证明为HashMap支持这一点的合理性。但是,仍然无法帮助您,因为您需要知道密钥(或可用于查找密钥的内容)才能再次查找。但是,您已经将密钥放在集合中。

您的第二个解决方案有效,因为您实际上并未将String的所有权授予地图,而是通过引用计数为其提供了对共享所有权建模的类型的所有权。 clone调用只是增加了引用计数,这模拟了很多动态语言如何解决这个问题。

use std::collections::HashMap;
use std::rc::Rc;

fn main() {
    let mut map = HashMap::new();
    let data = Rc::new("data".to_string());
    map.insert(data.clone(), 5);

    let v = map.get(&data);
    println!("{:?}", v);
}