Translate

jueves, 10 de agosto de 2023

Tiempos de vida en estructuras de datos


 Si un tipo de datos almacena datos prestados, debe anotarse con un tiempo de vida:

#[derive(Debug)]

struct Highlight<'doc>(&'doc str);


fn erase(text: String) {

    println!("Bye {text}!");

}


fn main() {

    let text = String::from("The quick brown fox jumps over the lazy dog.");

    let fox = Highlight(&text[4..19]);

    let dog = Highlight(&text[35..43]);

    // erase(text);

    println!("{fox:?}");

    println!("{dog:?}");

}


Si corremos esto: 

$ cargo run

   Compiling hello_cargo v0.1.0 (/home/emanuel/Projects/rust/hello_cargo)

warning: function `erase` is never used

 --> src/main.rs:7:4

  |

7 | fn erase(text: String) {

  |    ^^^^^

  |

  = note: `#[warn(dead_code)]` on by default


warning: `hello_cargo` (bin "hello_cargo") generated 1 warning

    Finished dev [unoptimized + debuginfo] target(s) in 1.80s

     Running `target/debug/hello_cargo`

Highlight("quick brown fox")

Highlight("lazy dog")

Pero si descomentamos esta linea // erase(text); y corremos:

$ cargo run

   Compiling hello_cargo v0.1.0 

error[E0505]: cannot move out of `text` because it is borrowed

  --> src/main.rs:19:11

   |

15 |     let fox = Highlight(&text[4..19]);

   |                          ---- borrow of `text` occurs here

...

19 |     erase(text);

   |           ^^^^ move out of `text` occurs here

20 |

21 |     println!("{fox:?}");

   |                --- borrow later used here


For more information about this error, try `rustc --explain E0505`.

error: could not compile `hello_cargo` due to previous error

  • En el ejemplo anterior, la anotación en Highlight impone que los datos subyacentes al &str contenido vivan al menos tanto tiempo como cualquier instancia de Highlight que use esos datos.
  • Si el texto se consume antes del final de la vida útil del fox (o del dog), el comprobador de préstamos arroja un error.
  • Los tipos con datos prestados obligan a los usuarios a conservar los datos originales. Esto puede ser útil para crear vistas ligeras, pero generalmente las hace un poco más difíciles de usar.
  • Cuando sea posible, haga que las estructuras de datos sean propietarias de sus datos directamente.
  • Algunas estructuras con múltiples referencias internas pueden tener más de una anotación de por vida. Esto puede ser necesario si existe la necesidad de describir las relaciones de duración entre las propias referencias, además de la duración de la estructura en sí. Esos son casos de uso muy avanzados.