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

问题描述 投票:5回答:1

我想插入一个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类型访问其中的元素,而无需额外分配。

rust
1个回答
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);
}
© www.soinside.com 2019 - 2024. All rights reserved.