2015-09-04 90 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沒有考慮它。 –