2016-05-16 39 views
1

我指望一個單詞出現在麥克白次數:「借來的價值不活足夠長的時間」,似乎怪說錯話

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

這個鏽barfs,他說:

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是這裏的問題?

回答

6

l

這不是指向的怪,真的。再次查看錯誤信息:

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

錯誤標記指向的unwrapl呼叫。

當問題是w

這不是真的。 lResult<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; 
    } 
} 
4

的錯誤是正確的,而且錯在這裏。 l是怪罪,因爲w生活只有l(和l.unwrap())和l壽命不夠長,以將其放入更高範圍的散列映射。

實際上,你只需要看看其他變量依賴於編譯器所抱怨的變量的生命週期。

但是Rust最近也在改進錯誤報告,所以我想raise this case as potential bug

相關問題