Saltar al contenido

¿Por qué se necesitan tiempos de vida explícitos en Rust?

Investigamos en todo internet y así de este modo mostrarte la solución a tu duda, en caso de dudas deja la duda y te contestaremos sin falta.

Solución:

Todas las otras respuestas tienen puntos destacados (el ejemplo concreto de fjh donde se necesita una vida útil explícita), pero les falta uno key cosa: ¿por qué se necesitan tiempos de vida explícitos cuando el compilador le dirá que los entendió mal?

Esta es en realidad la misma pregunta que “por qué se necesitan tipos explícitos cuando el compilador puede inferirlos”. Un ejemplo hipotético:

fn foo() -> _   
    ""

Por supuesto, el compilador puede ver que estoy devolviendo un &'static str, entonces, ¿por qué el programador tiene que escribirlo?

La razón principal es que, si bien el compilador puede ver lo que hace su código, no sabe cuál era su intención.

Las funciones son un límite natural para bloquear los efectos de cambiar el código. Si permitiéramos que las vidas útiles se inspeccionaran por completo desde el código, entonces un cambio de aspecto inocente podría afectar las vidas útiles, lo que podría causar errores en una función lejana. Este no es un ejemplo hipotético. Según tengo entendido, Haskell tiene este problema cuando confía en la inferencia de tipos para funciones de nivel superior. Rust cortó ese problema en particular de raíz.

También hay un beneficio de eficiencia para el compilador: solo se deben analizar las firmas de función para verificar los tipos y la vida útil. Más importante aún, tiene un beneficio de eficiencia para el programador. Si no tuviéramos tiempos de vida explícitos, ¿qué hace esta función?

fn foo(a: &u8, b: &u8) -> &u8

Es imposible saberlo sin inspeccionar la fuente, lo que iría en contra de una gran cantidad de mejores prácticas de codificación.

al inferir una asignación ilegal de una referencia a un ámbito más amplio

Ámbitos son vidas, esencialmente. Un poco más claro, toda una vida 'a es un parámetro de vida útil genérico que se puede especializar con un alcance específico en tiempo de compilación, según el sitio de la llamada.

son tiempos de vida explícitos realmente necesarios para prevenir […] errores?

Para nada. vidas son necesarios para evitar errores, pero se necesitan tiempos de vida explícitos para proteger la poca cordura que tienen los programadores.

Echemos un vistazo al siguiente ejemplo.

fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> &'a u32 
    x


fn main() 
    let x = 12;
    let z: &u32 = 
        let y = 42;
        foo(&x, &y)
    ;

Aquí, las vidas explícitas son importantes. Esto compila porque el resultado de foo tiene la misma duración que su primer argumento ('a), por lo que puede sobrevivir a su segundo argumento. Esto se expresa por los nombres de por vida en la firma de foo. Si cambió los argumentos en la llamada a foo el compilador se quejaría de que y no vive lo suficiente:

error[E0597]: `y` does not live long enough
  --> src/main.rs:10:5
   |
9  |         foo(&y, &x)
   |              - borrow occurs here
10 |     };
   |     ^ `y` dropped here while still borrowed
11 | }
   | - borrowed value needs to live until here

La anotación de por vida en la siguiente estructura:

struct Foo<'a> 
    x: &'a i32,

especifica que un Foo instancia no debería sobrevivir a la referencia que contiene (x campo).

El ejemplo que encontró en el libro Rust no ilustra esto porque f y y las variables quedan fuera del alcance al mismo tiempo.

Un mejor ejemplo seria este:

fn main() 
    let f : Foo;
    
        let n = 5;  // variable that is invalid outside this block
        let y = &n;
        f = Foo  x: y ;
    ;
    println!("", f.x);

Ahora, f realmente sobrevive a la variable señalada por f.x.

valoraciones y reseñas

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *