Анотації тривалісті життя
Посилання має тривалість життя, яка не повинна “пережити” значення, на яке воно посилається. Це перевіряється чекером запозичень.
Тривалість життя може бути неявною - це те, що ми бачили досі. Часи життя також можуть бути явними: &'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.
У поширених випадках час життя можна опустити, як описано на наступному слайді.