Анотації тривалісті життя

Посилання має тривалість життя, яка не повинна "пережити" значення, на яке воно посилається. Це перевіряється чекером запозичень.

Тривалість життя може бути неявною - це те, що ми бачили досі. Часи життя також можуть бути явними: &'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:?}");
}
This slide should take about 10 minutes.

У цьому прикладі компілятор не знає, яку тривалість життя виводити для p3. Якщо зазирнути у тіло функції, то можна з упевненістю припустити, що час життя p3 є меншим з двох: p1 та p2. Але так само, як і типи, Rust вимагає явних анотацій тривалості життя для аргументів функції та значень, що повертаються.

Додає 'a відповідним чином до left_most:

fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {

Це говорить, що "за умови, що p1 і p2 живуть довше за 'a, значення, що повертається, живе принаймні 'a.

У поширених випадках час життя можна опустити, як описано на наступному слайді.