Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Anotações de Tempo de Vida

Uma referência tem um tempo de vida (lifetime), que não deve “sobreviver” ao valor ao qual se refere. Isso é verificado pelo borrow checker (verificador de empréstimo).

O tempo de vida pode ser implícito - isso é o que vimos até agora. Os tempos de vida também podem ser explícitos: &'a Point, &'document str. Os tempos de vida começam com ' e 'a é um nome padrão típico. Leia &'a Point como “um Point emprestado que é válido por pelo menos o tempo de vida a”.

Os tempos de vida são sempre inferidos pelo compilador: você não pode atribuir um tempo de vida por conta própria. Anotações explícitas de tempo de vida criam restrições onde há ambiguidade; o compilador verifica se há uma solução válida.

Os tempos de vida se tornam mais complicados ao considerar a passagem de valores para e a devolução de valores de funções.

#[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); // Qual é o tempo de vida de p3?
    println!("p3: {p3:?}");
}
This slide should take about 10 minutes.

Neste exemplo, o compilador não sabe qual tempo de vida inferir para p3. Olhando dentro do corpo da função nos mostra que ele só pode assumir com segurança que o tempo de vida de p3 é o mais curto de p1 e p2. Mas assim como os tipos, o Rust requer anotações explícitas de tempos de vida nos argumentos e valores de retorno da função.

Adicione 'a apropriadamente a left_most (mais à esquerda):

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

Isto diz, “dado p1 e p2 que sobrevivem a 'a, o valor de retorno vive por pelo menos 'a.

Em casos comuns, os tempos de vida podem ser omitidos, como descrito no próximo slide.