2017-06-26 2 views
15

これまでは、それを生み出したステートメントの評価の終了時に一時的なものが破壊されたと仮定しました。一時的に破壊されるのはいつですか?

ただし、structのフィールドを一時的に初期化するときに例外が発生しているようです。

PeterHallは親切に私は を簡素化しましたhis answerにコメント、簡単なcode sample illustrating the differenceを提供するには少し複雑:

struct Wrapper<'a> { 
    cmd: &'a Cmd<'a>, 
} 

struct Cmd<'a> { 
    args: &'a Option<String>, 
} 

impl <'a> Cmd<'a> { 
    fn new(args: &'a Option<String>) -> Cmd<'a> { 
     Cmd { 
      args: args, 
     } 
    } 
} 

pub fn main() { 
    // OK 
    let cmd = Cmd { 
     args: &None, 
    }; 

    // OK 
    let cmd = Wrapper { 
     cmd: &Cmd { 
      args: &None, 
     } 
    }; 

    // Lifetime error 
    let cmd = Some(Cmd { 
     args: &None, 
    }); 

    // Lifetime error 
    let cmd = Cmd::new(&None); 
} 

ので、一時的に破壊されたときのための正確な規則は何ですか?第一、第二、失敗ラインで

+0

説明は分かりませんが、一貫性がないことは確かです。 – Boiethios

+1

「ライフタイムチェックは関数境界で停止する」というアスペクトに関連しています。ワーキングケースは構造体イニシャライザを持っているため、コンパイラにとってより透過的ですが、失敗した場合は関数呼び出しです。 – Shepmaster

+0

@Shepmaster:これは実際には、すべての借用がローカル変数のフィールドで独立して機能するが、関数呼び出しでは機能しないので、このようなものになる可能性があります。 –

答えて

1

見てみましょう:

let cmd = Cmd::new(&None); 

&Noneは、単一のラインの寿命が一時的に作成します。 Cmd::newは、同じ有効期間を持つCmdを返します。次に、その一時的な変数をletという変数に格納しようとしました。

Rust reference states:一時右辺値は聞かせて 宣言は、しかし、一時的に

...代わりに の寿命を囲むブロックを作成しているに割り当てられているように作成されている

一時的にCmdの有効期間を延長しようとしましたが、それは一時的な&Noneの存続期間に依存します。その一時的なものは実際にはに格納されないため例外ですステートメントの終わりまで持続する一時的なものに関するルール)、その有効期間はcmdの有効期間よりも短く、生涯のエラーが発生します。

letの構造体とそのメンバーに適用されるため、直接構造体のステートメントが機能します。

Some(enum)で動作しないという事実は、私(または少なくとも欠けている機能)のバグのようです。

関連する問題