2017-12-11 14 views
3

TRPL book(第2版)の第2版に従っていますが、タスクの1つで少し混乱しています。 section 10.2(特性)の末尾に、Clone形質を使用してlargest関数を再実装するように求められます。 (この時点で私はまだ寿命については何も学んでいないことに注意してください。)私は、次のなぜこれは迷惑な参照ではありませんか?

fn largest<T: PartialOrd + Clone>(list: &[T]) -> &T { 
    let l = list.clone(); 
    let mut largest = &l[0]; 

    for item in l { 
     if item > &largest { 
      largest = item; 
     } 
    } 

    largest 
} 

を実装これは、クローン化されたリストの項目への参照を返します。そして、見て、それはコンパイルされます。これはなぜ迷惑な参照ではないのですか(section 4.2に記載されています)?

は、私の知る限りそれを理解するよう、largestlistの(クローン化)コピーの項目への参照が含まれていますが、lスコープの外に出るので、largestが終了した後の参照を無効にはなりませんか?タイプをlがないため

+1

Matthieuの答えは正しいです。あなたの関数の生涯明示的な署名は、基本的に 'fn最大<、a:T:PartialOrd + Clone>(リスト:& 'a [T]) - >&' a'です。 – ljedrz

+0

@ljedrzありがとう@ljedrz次の章の後でこれを再訪しますが、意味が正確に推測されれば、私の出力はリストを参照して生涯( '' a')を共有します入力がまだ生きているので)、そうですか? – m00am

+0

はい、正確です。 – ljedrz

答えて

8

あなたはそれがないと思う:

fn largest<T: PartialOrd>(list: &[T]) -> &T { 
    let l: &[T] = list.clone(); 
    let mut largest = &l[0]; 

    for item in l { 
     if item > &largest { 
      largest = item; 
     } 
    } 

    largest 
} 

lが実際にちょうど同じ寿命で、スライス自体を返すスライスをクローニングしすぎ参照、です。

したがって、参照をスライスに入れても問題ありません。戻り値は元のスライスを借りています。

+0

ありがとうございました:)これは私を助けました。また、私に 'let l:&[T]'を使用できることを思い出させてくれてありがとう。 – m00am

+8

@ m00am:デバッグのために便利な方法は、 'let x:()= ...;'を使ってコンパイラにエラーメッセージの型を教えさせることです。 –

関連する問題