2015-09-04 1 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)); 

Как я могу сделать это с Rust 1.2.0?

В идеале я хотел бы поместить ключ в HashMap, но сохранить ссылку на него и разрешить доступ к элементам в нем с &str типами без дополнительного выделения.

+1

Существует ряд проблем с вашим кодом, поэтому трудно понять, что именно вы пытаетесь выполнить. Вы знаете о [Rust PlayPen] (https://play.rust-lang.org/?gist=d889c51118aeb8433832&version=stable)? Это отличный способ создать минимальную версию кода, которая фокусируется на вашей конкретной проблеме, поскольку она устраняет все эти досадные ошибки (например, отсутствующие «mut» в 'let map'), которые загрязняют ваше предложение. –

+0

@ MatthieuM. крошечный нит, но в какой-то момент он был переименован в «Rust Playground». Я заметил, что на днях сам :-) – 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 не рассматривались. –

Смежные вопросы