0

What I want to do is:

let mut a = HashMap::<String, Option<&str>>::new();
let s = "123".to_string();
let v = Some(&s[..]);
a.insert(s, v); // won't work 
// let entry = a.raw_entry_mut().from_key(&s).or_insert(s, v); // won't work
for (k, v) in a.iter_mut() { // this works, but I'll need to find the entry after insertion
    *v = Some(&k);
}

That is, I want to have a map with Value holding a reference to it's key. However the code refuses to compile:

error[E0505]: cannot move out of `s` because it is borrowed
 --> src/main.rs:9:14
  |
8 |     let v = Some(&s[..]);
  |                   - borrow of `s` occurs here
9 |     a.insert(s, v); 
  |              ^  - borrow later used here
  |              |
  |              move out of `s` occurs here

For more information about this error, try `rustc --explain E0505`.

There is a workaround, but requires cloning the String:

let id = "123".to_string();
HashMap::from([
    (id.clone(), Some(id)),
]);
Jun Xiao
  • 1
  • 1
  • That is basically a self-referential structure, which is not something Rust looks fondly upon, as it's a source of dangling references: what's supposed to happen if you `remove()` the key, and keep the value around? So yes you either need to duplicate the key, or you need to use an Rc/Arc in order to share the ownership. – Masklinn Mar 10 '22 at 13:55
  • Or you could store as the map's value the data necessary to borrow from the key, e.g. the slice index/range. – eggyal Mar 10 '22 at 14:12
  • @Masklinn Thx for the Reply! The rust book didn't warn me that I could create dangling references by self-referencing. – Jun Xiao Mar 10 '22 at 14:23
  • @Jmb Yeah quite a lot. Thx. I recall reading the Pin trait in the rustonomicon but that part was too hard for me so I skimmed it. – Jun Xiao Mar 10 '22 at 14:26

0 Answers0