Анотації тривалісті життя
Посилання має тривалість життя, яка не повинна "пережити" значення, на яке воно посилається. Це перевіряється чекером запозичень.
Тривалість життя може бути неявною - це те, що ми бачили досі. Часи життя також можуть бути явними: &'a Point'',
&'document str''. Тривалість життя починається з '
, а 'a
є типовим іменем за замовчуванням. Читати &'a Point
як "запозичений Point
, який є дійсним принаймні протягом тривалості життя a
".
Тривалість життя завжди визначається компілятором: ви не можете призначити час життя самостійно. Явні анотації часу життя створюють обмеження там, де існує неоднозначність; компілятор перевіряє, чи існує правильний розв'язок.
Часи життя ускладнюються, якщо врахувати передачу значень у функції та повернення значень з них.
#[derive(Debug)] struct Point(i32, i32); fn left_most(p1: &Point, p2: &Point) -> &Point { if p1.0 < p2.0 { p1 } else { p2 } } fn main() { let p1: Point = Point(10, 10); let p2: Point = Point(20, 20); let p3 = left_most(&p1, &p2); // Яка тривалість життя p3? println!("p3: {p3:?}"); }
У цьому прикладі компілятор не знає, яку тривалість життя виводити для p3
. Якщо зазирнути у тіло функції, то можна з упевненістю припустити, що час життя p3
є меншим з двох: p1
та p2
. Але так само, як і типи, Rust вимагає явних анотацій тривалості життя для аргументів функції та значень, що повертаються.
Додає 'a
відповідним чином до left_most
:
fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {
Це говорить, що "за умови, що p1 і p2 живуть довше за 'a
, значення, що повертається, живе принаймні 'a
.
У поширених випадках час життя можна опустити, як описано на наступному слайді.