2015-09-04 86 views
3

我想插入到HashMap中,但保留密钥的不可变借用以传递到地方。在我的情况下,键是字符串。如何在密钥插入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)); 

但是这需要一个克隆。

这一个工作,直到锈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)); 

我怎么能带锈1.2.0做到这一点?

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

+1

您的代码存在一系列问题,因此很难准确理解您要完成的工作。你知道[Rust PlayPen](https://play.rust-lang.org/?gist=d889c51118aeb8433832&version=stable)吗?这是生成最小版本代码的好方法,专注于您的确切问题,因为它消除了污染您的提议的所有麻烦错误(如'let map中缺少的'mut')。 –

+0

@MatthieuM。小尼特,但在某些时候,它被改名为“铁锈游乐场”。我注意到,有一天我自己:-) – Shepmaster

+0

对不起,错误的家伙,现在修复。 –

回答

7

简短的回答是,你不能。当你插入东西到HashMap,你转让所有权。这样做会使您对密钥的任何引用无效,因为密钥是移到了映射分配的内存中。

接受的RFC 1194提出了一种方法来获得对由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); 
} 
+0

这个解决方案非常棒!虽然我不能用'&str'类型访问我的地图中的数据,这是必须的。 :/ –

+0

这个RFC看起来像我需要的,太糟糕了,HashMaps没有考虑它。 –