2017-06-26 8 views
15

Do tej pory zakładałem, że tymczasowy został zniszczony na końcu oceny oświadczenia, które go zainicjowało.Kiedy jest tymczasowo zniszczony?

Jednak wydaje się, że wystąpił wyjątek podczas używania tymczasowego w celu zainicjowania pola struct.

PeterHall usłużnie warunkiem prosty code sample illustrating the difference w komentarzu do his answer, co mam uproszczone trochę skomplikowane:

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

tak, jaka jest dokładna zasada gdy tymczasowa jest zniszczona? wygląd

+0

Nie znam wyjaśnienia, ale na pewno nie jest to zgodne. – Boiethios

+1

Odczucia związane z aspektem "sprawdzanie żywotności zatrzymuje się na granicach funkcji". Sprawa ma wbudowany inicjalizator struktury, przez co jest bardziej "przezroczysty" dla kompilatora, a niepowodzenie to wywołanie funkcji. – Shepmaster

+0

@Shepmaster: To może być coś takiego, po wszystkim pożyczanie działa niezależnie dla pól zmiennej lokalnej, ale nie dla wywołań funkcji. –

Odpowiedz

1

Przejdźmy na drugą pierwszej linii gdyż w przeciwnym razie:

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

&None tworzy tymczasowy z życia w jednej linii. Cmd::new zwraca wartość Cmd, która ma takie samo życie. Następnie próbujemy zapisać ten tymczasowy w zmiennej z let.

Rust reference states:

Kiedy tymczasowa RValue jest tworzony, który jest przypisany do zawiedziony oświadczenie, jednak tymczasowy jest tworzony z życia otaczającego bloku zamiast ...

on próbuje zwiększyć żywotność Cmd tymczasowego, ale to zależy od trwania &None tymczasowej, a ponieważ nie jest tymczasowy faktycznie przechowywane w let (wyjątkiem do reguły dotyczącej tymczasów trwających do końca wyciągu), jej żywotność jest mniejsza niż czas życia cmd i pojawia się błąd życia.

Bezpośrednie instrukcje struct działają, ponieważ okres istnienia let dotyczy struktury i jej elementów.

Fakt, że nie działa dla Some (wyliczenie), wydaje mi się błędem (lub przynajmniej brakującą funkcją).