Funciones

Ignorando elisión, las signaturas de funciones con tiempos de vida tienen algunas restricciones:

  • cualquier referencia debe tener una vida útil anotada.
  • cualquier referencia que se devuelva debe tener la misma duración que una entrada o ser static.

Además, ten en cuenta que la devolución de referencias sin entrada está prohibida si da como resultado la devolución de referencias a datos no válidos. El siguiente ejemplo muestra algunas formas válidas de funciones con vida útil:

// Una referencia de entrada con vida útil `'a` que debe vivir al menos tan
// largo como la función.
fn imprime_uno<'a>(x: &'a i32) {
    println!("`imprime_uno`: x es {}", x);
}

// Las referencias mutables también son posibles con vidas útiles.
fn agrega_uno<'a>(x: &'a mut i32) {
    *x += 1;
}

// Varios elementos con diferentes tiempos de vida. En este caso,
// estaría bien que ambos tuvieran la misma vida útil `'a`, pero
// en casos más complejos, pueden ser necesarias diferentes vidas útiles.
fn imprime_multipes<'a, 'b>(x: &'a i32, y: &'b i32) {
    println!("`imprime_multipes`: x es {}, y es {}", x, y);
}

// Devolver referencias que se han pasado es aceptable.
// Sin embargo, se debe devolver la vida útil correcta.
fn pasa_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x }

//fn salida_invalida<'a>() -> &'a String { &String::from("foo") }
// Lo anterior no es válido: `'a` debe vivir más tiempo que la función.
// Aquí, `&String::from("foo")` crearía una `String`, seguida de una referencia.
// Luego, los datos se eliminan al salir del ámbito, dejando una referencia a datos
// no válidos que se devolverán.

fn main() {
    let x = 7;
    let y = 9;
    
    imprime_uno(&x);
    imprime_multipes(&x, &y);
    
    let z = pasa_x(&x, &y);
    imprime_uno(z);

    let mut t = 3;
    agrega_uno(&mut t);
    imprime_uno(&t);
}

Ve también

funciones