error[E0597]: borrowed value does not live long enough in While loop

▼魔方 西西 提交于 2020-05-24 03:30:05

问题


I am really new to Rust, I am having trouble solving this error, but it only happens if I comment out the while statement , basicly I am asking values from the console and storing it in a HashMap:

use std::collections::HashMap;
use std::io;

fn main() {
    let mut customers = HashMap::new();
    let mut next_customer = true;
    while next_customer {
        let mut input_string = String::new();
        let mut temp_vec = Vec::with_capacity(3);
        let mut vec = Vec::with_capacity(2);
        println!("Insert new customer f.e = customer id,name,address:");
        io::stdin().read_line(&mut input_string);
        input_string = input_string.trim().to_string();
        for s in input_string.split(",") {
            temp_vec.push(s);
        }
        vec.push(temp_vec[1]);
        vec.push(temp_vec[2]);
        let mut key_value = temp_vec[0].parse::<i32>().unwrap();
        customers.insert(key_value, vec);
        next_customer = false;
    }
    println!("DONE");
}

The code results in the error

error[E0597]: `input_string` does not live long enough
  --> src/main.rs:14:18
   |
14 |         for s in input_string.split(",") {
   |                  ^^^^^^^^^^^^ borrowed value does not live long enough
...
20 |         customers.insert(key_value, vec);
   |         --------- borrow later used here
21 |         next_customer = false;
22 |     }
   |     - `input_string` dropped here while still borrowed

回答1:


As others have said the problem lies with the lifetime and/or type of the values getting put into the customers map.

customers.insert(key_value, vec);
   |         --------- borrow later used here

Often this happens when the compiler has decided to give an object a type that you didn't expect. To find out what it's doing you can force the type, and see how it complains. Changing the code to:

    let mut customers: HashMap<(),()> = HashMap::new();

Gives us two relevant errors:

20 |         customers.insert(key_value, vec);
   |                          ^^^^^^^^^ expected `()`, found `i32`
...
20 |         customers.insert(key_value, vec);
   |                                     ^^^ expected `()`, found struct `std::vec::Vec`
   |
   = note: expected unit type `()`
                 found struct `std::vec::Vec<&str>`

So the type that the compiler wants to give our customers object is HashMap<i32, Vec<&str>>

The problem is that the &str lifetime has got to be inside the block as we don't store the Strings anywhere, and they can't have 'static lifetime since they're user input.

This means we probably want a HashMap<i32,Vec<String>>.

Changing the code to use one of those gives us an error about vec not having the right type: It's getting deduced as a Vec<&str>, but we want a Vec<String>.

We have two options.

  1. Convert the vec to the right type just before we insert it into the map using customers.insert(key_value, vec.iter().map(|s| s.to_string()).collect()). (Though you may want to extract it to a variable for clarity).

  2. Explicitly change the type of vec to Vec<String>

Option 1 "just works". While option 2 leads us down a path of making similar changes closer and closer to the read_line call.

Once you've decided on the fix in option 1, you can remove the manual type annotations that were added to work out the fix, if you find them overly noisy.




回答2:


The issue is that you are passing around reference to underlying &str values that will get dropped. One way is to take the input string, trim and split it, then clone it going into the other vector.

let temp_vec: Vec<String> = input_string.trim().split(",").map(|t| t.to_string()).collect();
vec.push(temp_vec[1].clone());
vec.push(temp_vec[2].clone());


来源:https://stackoverflow.com/questions/60555208/errore0597-borrowed-value-does-not-live-long-enough-in-while-loop

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!