Tempos de vida (Lifetimes) em Chamadas de Função

Tempos de vida para argumentos de função e valores de retorno precisam ser completamente especificados, mas o Rust permite que eles sejam omitidos na maioria das vezes com algumas regras simples. Isso nĂŁo Ă© inferĂȘncia - Ă© apenas uma abreviação sintĂĄtica.

  • Cada argumento que nĂŁo tem uma anotação de tempo de vida Ă© dado um.
  • Se houver apenas um tempo de vida de argumento, ele Ă© dado a todos os valores de retorno nĂŁo anotados.
  • Se houver vĂĄrios tempos de vida de argumento, mas o primeiro for para self (self), esse tempo de vida Ă© dado a todos os valores de retorno nĂŁo anotados.
#[derive(Debug)]
struct Point(i32, i32);

fn cab_distance(p1: &Point, p2: &Point) -> i32 {
    (p1.0 - p2.0).abs() + (p1.1 - p2.1).abs()
}

fn nearest<'a>(points: &'a [Point], query: &Point) -> Option<&'a Point> {
    let mut nearest = None;
    for p in points {
        if let Some((_, nearest_dist)) = nearest {
            let dist = cab_distance(p, query);
            if dist < nearest_dist {
                nearest = Some((p, dist));
            }
        } else {
            nearest = Some((p, cab_distance(p, query)));
        };
    }
    nearest.map(|(p, _)| p)
}

fn main() {
    println!(
        "{:?}",
        nearest(
            &[Point(1, 0), Point(1, 0), Point(-1, 0), Point(0, -1),],
            &Point(0, 2)
        )
    );
}
This slide should take about 5 minutes.

Neste exemplo, cab_distance Ă© trivialmente omitido.

A função nearest fornece outro exemplo de uma função com vĂĄrias referĂȘncias em seus argumentos que requer anotação explĂ­cita.

Tente ajustar a assinatura para “mentir” sobre os tempos de vida retornados:

fn nearest<'a, 'q>(points: &'a [Point], query: &'q Point) -> Option<&'q Point> {

Isso não irå compilar, demonstrando que as anotaçÔes são verificadas quanto à validade pelo compilador. Observe que esse não é o caso dos ponteiros brutos (raw pointers) (inseguros), e essa é uma fonte comum de erros com Rust inseguro.

Os alunos podem perguntar quando usar tempos de vida. Os emprĂ©stimos do Rust sempre tĂȘm tempos de vida. Na maioria das vezes, a omissĂŁo e a inferĂȘncia de tipo significam que eles nĂŁo precisam ser escritos. Em casos mais complicados, as anotaçÔes de tempo de vida podem ajudar a resolver a ambiguidade. Muitas vezes, especialmente ao prototipar, Ă© mais fĂĄcil trabalhar com dados owned (owned data) clonando valores quando necessĂĄrio.