2017-01-22 33 views
19

Biorąc pod uwagę ten kod:Dlaczego jest związany "T:" a "wymagany do przechowywania odniesienia` & 'a T`?

struct RefWrapper<'a, T> { 
    r: &'a T, 
} 

... kompilator narzeka:

error: the parameter type T may not live long enough

consider adding an explicit lifetime bound T: 'a so that the reference type &'a T does not outlive the data it points at.

Widziałem ten błąd wielokrotnie już i tak daleko Właśnie słuchałem kompilator i wszystko działało w porządku . Jednak myśląc o tym więcej, nie rozumiem, dlaczego muszę napisać .

O ile rozumiem, jest to już niemożliwe do uzyskania takiego odniesienia. Posiadanie &'a T implikuje, że istnieje obiekt typu T, który żyje przez co najmniej 'a. Ale nie możemy przechowywać żadnych odniesień w tym obiekcie, które wskazują na dane o krótszym czasie życia niż 'a. To byłby już spowodować błąd kompilatora.

W tym sensie jest już niemożliwe uzyskanie &'a T gdzie T nie przeżyje 'a. Dlatego dodatkowa adnotacja (T: 'a) nie powinna być konieczna.

Mam rację? Czy jestem w błędzie, a jeśli tak, to w jaki sposób mogę złamać kod, jeśli T: 'a nie byłaby wymagana?


Linki:

+1

I Zapytany o #rust i wygląda na to, że [ten kod] (https: // github.com/rust-lang/rust/issues/24622 # issuecomment-94761287) złamałoby rzeczy, gdyby wymaganie "T:" a "zostało zniesione. Ale tak naprawdę nie rozumiem tego kodu, a na razie przestanę próbować. Mam nadzieję, że ktoś, kto rozumie problem, odpowie w międzyczasie^_^ –

+0

[Podobne dokumenty RFC z sierpnia 2017 r.] (Https://github.com/rust-lang/rfcs/pull/2093) –

Odpowiedz

15

Jest częścią sensowności zasad. Typ &'a T jest dobrze uformowany tylko wtedy, gdy T: 'a ("T outlives" a ", jest wymagany, ponieważ mamy referencję, do której możemy uzyskać dostęp w zakresie 'a, wskazana wartość w T musi być ważna co najmniej zakres).

struct RefWrapper<'a, T> to typ rodzajowy i mówi można wejściowe całe życie 'x i rodzaj U i uzyskać typ RefWrapper<'x, U> powrotem. Jednak ten typ niekoniecznie jest dobrze uformowany lub nawet implementowany, o ile nie zostanie spełniony wymóg.

Wymaganie to wynika z szczegółów wdrożenia; niekoniecznie jest tak, że T i 'a są używane razem, jak &'a T w elementach wewnętrznych struktury. Wymóg dobrego uformowania musi być promowany do publicznego interfejsu struktury RefWrapper, tak aby wymagania dotyczące tworzenia typu RefWrapper<'_, _> były publiczne, nawet jeśli wewnętrzna implementacja nie jest.

(Są inne miejsca, gdzie sam wymóg T: 'a wraca ale jest implict:

pub fn foo<'a, T>(x: &'a T) { } 

możemy dostrzec różnicę. Tutaj typ &'a T jest częścią publicznych API, zbyt)

+0

To ma sens, dziękuję <3 –