"Задолженность недолговечна", похоже, виноват в неправильной

57
3

Я рассчитываю, сколько раз в Macbeth появляется слово:

use std::io::{BufRead, BufReader};
use std::fs::File;
use std::collections::HashMap;

fn main() {
let f = File::open("macbeth.txt").unwrap();
let reader = BufReader::new(f);
let mut counts = HashMap::new();

for l in reader.lines() {
for w in l.unwrap().split_whitespace() {
let count = counts.entry(w).or_insert(0);
*count += 1;
}
}

println!("{:?}", counts);
}

Положите на него ржавчину, сказав:

error[E0597]: borrowed value does not live long enough
--> src/main.rs:14:9
|
11 | for w in l.unwrap().split_whitespace() {
| ---------- temporary value created here
...
14 | }
| ^ temporary value dropped here while still borrowed
...
18 | }
| - temporary value needs to live until here
|
= note: consider using a 'let' binding to increase its lifetime

Фактическая проблема заключается в том, что w является ссылкой, и поэтому ее изменение на w.to_string() решает ее. Я не понимаю, почему компилятор Rust указывает на вину в l, когда проблема - w. Как я могу предположить, что проблема w здесь?

спросил(а) 2016-05-17T01:42:00+03:00 4 года, 5 месяцев назад
1
Решение
115

указывает на обвинение в l

Это не так. Просмотрите сообщение об ошибке еще раз:

     for w in l.unwrap().split_whitespace() {
---------- temporary value created here

Маркер ошибки указывает на вызов unwrap на l.

когда речь идет о w

Это не так. l имеет тип Result<String>. Когда вы вызываете unwrap, вы получаете String, а затем split_whitespace возвращает ссылки на эту строку. Эти ссылки живут только до тех пор, пока строка, но ваш код пытается помещать их в хэш-карту, которая будет жить дольше, чем строка. Проблема в том, что l.unwrap() не проживает достаточно долго, а w - просто ссылка на вещь, которая не живет достаточно долго.

По идее, это та же проблема, что и этот код:

use std::collections::HashMap;

fn main() {
let mut counts = HashMap::new();

{
let s = String::from("hello world");
counts.insert(&s, 0);
}

println!("{:?}", counts);
}

Что также указывает на s и говорит, что он не живет достаточно долго (потому что это не так).

Правильное решение состоит в том, чтобы преобразовать каждое слово в принадлежащую ему String которую может удерживать HashMap:

for l in reader.lines() {
for w in l.unwrap().split_whitespace() {
counts.entry(w.to_string()).or_insert(0) += 1;
}
}

ответил(а) 2016-05-17T02:58:00+03:00 4 года, 5 месяцев назад
91

Здесь ошибка и правильная, и неправильная. l обвиняется, потому что w живет только до тех пор, пока ll.unwrap()), и l не живет достаточно долго, чтобы помещать его в hashmap в более широком диапазоне.

На практике вам просто нужно посмотреть, какие другие переменные зависят от времени жизни переменной, с которой жалуется компилятор.


Но в последнее время Rust также работает над улучшением отчетности об ошибках, поэтому я бы поднял этот случай как потенциальную ошибку.

ответил(а) 2016-05-17T03:00:00+03:00 4 года, 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема