我想插入一个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(©);
let two = map.get(&*as_string("data"));
println!("{:?}", (one, two));
如何使用Rust 1.2.0实现此目的?
理想情况下,我希望将一个键放入HashMap,但保留对它的引用,并允许我使用&str
类型访问其中的元素,而无需额外分配。
答案 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);
}