Saltar al contenido principal
eLearner.app
Módulo 6 · Lección 1 de 211/14 en el curso~15 min
Lecciones del módulo (1/2)

Lifetimes y referencias

En Rust, cada referencia tiene un lifetime (duración), que corresponde al ámbito (scope) dentro del cual esa referencia es válida. La mayoría de las veces los lifetimes son implícitos y deducidos por el compilador gracias a las reglas de elisión. Sin embargo, cuando la relación entre los lifetimes de diferentes referencias es ambigua, debemos anotarlos explícitamente.

El objetivo principal de los lifetimes es prevenir las dangling references (referencias a datos que ya han sido liberados de la memoria).


La Sintaxis de las Anotaciones de Lifetimes

Los nombres de los lifetimes comienzan con un apóstrofo (') y suelen escribirse con letras minúsculas muy cortas (como 'a). Las anotaciones de lifetimes no cambian la duración real de las variables, sino que indican al compilador la relación de validez entre las referencias recibidas y las devueltas eventualmente.

Por ejemplo, si una función toma dos parámetros que son referencias a cadena y devuelve una referencia a cadena, y queremos que la referencia devuelta sea válida mientras ambos parámetros de entrada sean válidos, usamos:

Code
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

Lifetimes en las Estructuras de datos

Si una estructura de datos contiene un campo que es una referencia, debemos anotar explícitamente el lifetime en esa referencia para garantizar que la instancia de la struct no pueda sobrevivir a los datos a los que se refiere:

Code
struct ImportantExcerpt<'a> {
    part: &'a str,
}

fn main() {
    let novel = String::from("Chiamami Ismaele. Alcuni anni fa...");
    let first_sentence = novel.split('.').next().unwrap();
    let i = ImportantExcerpt {
        part: first_sentence,
    };
}

El Lifetime Estático

El lifetime 'static es un lifetime especial que dura toda la duración de la ejecución del programa. Todos los literales de cadena (&str) tienen implícitamente un lifetime 'static porque se codifican directamente dentro del ejecutable binario.

Code
let s: &'static str = "Ho un lifetime statico.";

Pruébalo tú

Ejercicio 1: La función longest

Ejercicio#rust.m6.l1.e1
Intentos: 0Cargando...

Escribe una función llamada longest<'a> que acepte dos parámetros, x de tipo &'a str e y de tipo &'a str, y devuelva un valor de tipo &'a str. Dentro de la función, usa un constructor if/else para devolver el parámetro x si su longitud es mayor que la de y; de lo contrario, devuelve y.

Cargando editor...
Mostrar pista

Declara la firma con `fn longest<'a>(x: &'a str, y: &'a str) -> &'a str`. Luego usa `if x.len() > y.len() { x } else { y }`.

Solución disponible después de 3 intentos

Ejercicio 2: Estructuras con referencias

Ejercicio#rust.m6.l1.e2
Intentos: 0Cargando...

Define una estructura llamada Excerpt<'a> que contenga un solo campo llamado part de tipo &'a str. En el main, crea una variable de cadena llamada text e instancia una variable excerpt de tipo Excerpt prestando una referencia a text. Imprime en pantalla excerpt.part.

Cargando editor...
Mostrar pista

Usa `struct Excerpt<'a> { part: &'a str }`. En el main instánciala con `Excerpt { part: &text }`.

Solución disponible después de 3 intentos

Ejercicio 3: Referencias estáticas

Ejercicio#rust.m6.l1.e3
Intentos: 0Cargando...

Declara una variable llamada message con anotación de tipo explícita para el lifetime estático (&'static str), asignándole un valor literal de cadena. Imprime en pantalla el valor de message.

Cargando editor...
Mostrar pista

Usa la sintaxis `let message: &'static str = 'Messaggio statico!';` para anotar explícitamente el lifetime estático.

Solución disponible después de 3 intentos