How to make Rust temporary value live longer?

Viewed 233

I'm still learning Rust and have the following code.

use std::collections::BTreeMap;

#[derive(Debug)]
struct MyStruct {
    a: String,
    b: String,
}

fn main() {
    let mut hash = BTreeMap::new();

    let data = vec![
        MyStruct {
            a: "entry1".to_string(),
            b: "entry1 body".to_string(),
        },
        MyStruct {
            a: "entry2".to_string(),
            b: "entry2 body".to_string(),
        }
    ];

    let re = regex::Regex::new(r#".(\d)"#).unwrap();
    for item in &data {
        for m in re.captures_iter(&item.b) {
            hash.insert(&m[1].parse::<i32>().unwrap(), &item.a);
        }
    }

    println!("{:#?}", hash);
}

It generates an error:

error[E0716]: temporary value dropped while borrowed
  --> src\main.rs:26:26
   |
26 |             hash.insert(&m[1].parse::<i32>().unwrap(), &item.a);
   |             ----         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^          - temporary value is freed at the end of this statement
   |             |            |
   |             |            creates a temporary which is freed while still in use
   |             borrow later used here
   |
   = note: consider using a `let` binding to create a longer lived value

What's the correct way to fix it? I tried to put &m[1].parse::<i32>().unwrap() in a variable but of no avail.

1 Answers

The BTreeMap structure should either be the owner of the data and key inserted, or the data and key should have a 'static lifetime (same as HashMap and other collections). In this case, the key being used is i32, which has the Copy trait defined for it, so simply removing the & reference should pass the i32 value in as the key. For the data, you will either want to clone the string rather than & borrow, but you could also rewrite the loop to consume the data vector and pass the item.b string value in without the need to clone.

Related