Tiempos de Vida en Llamadas a Función

Además de tomar prestados sus argumentos, una función puede devolver un valor que se ha tomado prestado:

#[derive(Debug)]
struct Point(i32, i32);

fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a 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: &Point = left_most(&p1, &p2);
    println!("left-most point: {:?}", p3);
}
  • 'a es un parámetro genérico que infiere el compilador.
  • Los tiempos de vida comienzan por ' y 'a suele ser un nombre predeterminado habitual.
  • Lee &'a Point como “un Point prestado que es válido al menos durante el tiempo de vida de a”.
    • La parte al menos es importante cuando los parámetros están en ámbitos distintos.

En el ejemplo anterior, prueba lo siguiente:

  • Mueve la declaración de p2 y p3 a un nuevo ámbito ({ ... }), lo que dará como resultado el siguiente código:

    #[derive(Debug)]
    struct Point(i32, i32);
    
    fn left_most<'a>(p1: &'a Point, p2: &'a Point) -> &'a Point {
        if p1.0 < p2.0 { p1 } else { p2 }
    }
    
    fn main() {
        let p1: Point = Point(10, 10);
        let p3: &Point;
        {
            let p2: Point = Point(20, 20);
            p3 = left_most(&p1, &p2);
        }
        println!("left-most point: {:?}", p3);
    }

    Ten en cuenta que no se puede compilar, ya que p3 dura más tiempo que p2.

  • Restablece el espacio de trabajo y cambia la firma de la función a fn left_most<'a, 'b>(p1: &'a Point, p2: &'a Point) -> &'b Point. No se compilará porque la relación entre los tiempos de vida de 'a y 'b no está clara.

  • Otra forma de explicarlo:

    • Una función toma prestadas dos referencias a dos valores y devuelve otra referencia.
    • Esta debe proceder de una de esas dos entradas (o de una variable global).
    • ¿Cuál de ellas es? El compilador debe saberlo para que, en el sitio de la llamada, la referencia devuelta no se use durante más tiempo que una variable de la que procede la referencia.