2016-05-16 10 views
1

私は言葉がマクベスに表示された回数をカウントしていますのせいに思わ「借りた値が十分に長く住んでいないが、」間違ったこと

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()に変更すると解決します。私は、問題がwのときに、Rustコンパイラがlに責任を指摘している理由を知りません。 wがここで問題であると推測する方法はありますか?

答えて

6

それは本当に、ではないのですl

で非難を指しています。再びエラーメッセージを確認してください。

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

エラーマーカーがlunwrapのコールを指しています。

問題は本当に、それはありません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を指すと(それがないので)、それは十分に長く住んでいないと言います。

正解はHashMapはその後、保持することができます所有Stringに各単語を変換することです:

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

エラーがここに善悪両方です。 はl(および)とlの間だけ存在し、より高い範囲のハッシュマップに入れるのに十分な長さしかないため、lが非難されています。

実際には、コンパイラが不平を言う変数の寿命に依存する他の変数を調べるだけで済みます。

最近、エラー報告の改善にRustも働いているので、raise this case as potential bugとなります。

関連する問題