Naprawdę jestem naprawdę nowością rdzy, mam problemy z rozwiązaniem tego błędu, ale zdarza się tylko, jeśli komentuję jednocześnie oświadczenie, zgodnie z konsolą, pytam o wartości z konsoli i przechowywanie go w Hashmapie:

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");
}

Kodeks powoduje błąd

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
3
dreid 6 marzec 2020, 01:59

2 odpowiedzi

Najlepsza odpowiedź

Jak inni powiedzieli, że problem leży z całe życie i / lub typ wartości, które zostają umieszczone na mapie klientów.

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

Często dzieje się tak, gdy kompilator postanowił podać obiekt typ, którego nie spodziewałem. Aby dowiedzieć się, co robi, możesz zmusić typ i zobacz, jak się skarga. Zmiana kodu do:

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

Daje nam dwa istotne błędy:

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>`

Więc typ, który kompilator chce dać naszym obiektom klientom to HashMap<i32, Vec<&str>>

Problem polega na tym, że &str Lifetime musi być w bloku, ponieważ nie przechowuje String s nigdzie, a nie mogą mieć życia 'static, ponieważ są użytkownikami Wejście.

Oznacza to, że prawdopodobnie chcemy HashMap<i32,Vec<String>>.

Zmiana kodu, aby użyć jednego z tych daje nam błąd o vec Nie posiadający odpowiedniego typu: jest wydedukowana jako Vec<&str>, ale chcemy Vec<String>.

Mamy dwie opcje.

  1. Konwertuj VEC do odpowiedniego typu tuż przed włożeniem go do mapy za pomocą customers.insert(key_value, vec.iter().map(|s| s.to_string()).collect()). (Chociaż możesz go wyodrębnić do zmiennej dla jasności).

  2. Wyraźnie zmień typ VEC do Vec<String>

Opcja 1 "Just działa". Podczas gdy opcja 2 prowadzi nas na ścieżkę, co bliższe zmiany i bliżej połączenia read_line.

Po podjęciu decyzji o opcji W opcji 1 możesz usunąć adnotacje typu instrukcji, które zostały dodane, aby rozwiązać poprawkę, jeśli uważasz je za zbyt głośno.

4
Michael Anderson 6 marzec 2020, 03:55

Problem polega na tym, że przechodzisz do odniesienia do wartości podstawowych i strjów, które zostaną upuszczone. Jednym ze sposobów ma nabyć ciąg wejściowy, wykończenia i podzielić, a następnie klonuje go w innym wektorze.

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());
2
CyanRook 6 marzec 2020, 00:44