variable structur how example define struct rust lifetime

how - structur en c



¿Cuál es la diferencia entre ''& self'' y ''&'' a self ''? (1)

Lifetime ''a in fn foo(&''a self, ...) ... se define para impl<''a> , es decir, es lo mismo para todas las llamadas foo .

Lifetime ''a in fn get_mut<''a>(&''a mut self) ... se define para la función. Las diferentes llamadas de get_mut pueden tener diferentes valores para ''a .

Tu codigo

impl<''a> Foo<''a> { fn foo(&''a self, path: &str) -> Boo<''a> { /* */ } }

no es la expansión de la vida elida. Este código vincula el tiempo de vida de un "préstamo &''a self con la vida de la estructura Foo<''a> . Si Foo<''a> es invariante sobre ''a , entonces el self debería permanecer prestado siempre que ''a .

La expansión correcta de la vida útil elida es

impl<''a> Foo<''a> { fn foo<''b>(&''b self, path: &str) -> Boo<''b> { /* */ } }

Este código no depende de la varianza de la estructura Foo para poder tomar prestada self vida más corta.

Ejemplo de diferencias entre estructuras variantes e invariantes.

use std::cell::Cell; struct Variant<''a>(&''a u32); struct Invariant<''a>(Cell<&''a u32>); impl<''a> Variant<''a> { fn foo(&''a self) -> &''a u32 { self.0 } } impl<''a> Invariant<''a> { fn foo(&''a self) -> &''a u32 { self.0.get() } } fn main() { let val = 0; let mut variant = Variant(&val);// variant: Variant<''long> let mut invariant = Invariant(Cell::new(&val));// invariant: Invariant<''long> { let r = variant.foo(); // Pseudocode to explain what happens here // let r: &''short u32 = Variant::<''short>::foo(&''short variant); // Borrow of `variant` ends here, as it was borrowed for `''short` lifetime // Compiler can do this conversion, because `Variant<''long>` is // subtype of Variant<''short> and `&T` is variant over `T` // thus `variant` of type `Variant<''long>` can be passed into the function // Variant::<''short>::foo(&''short Variant<''short>) } // variant is not borrowed here variant = Variant(&val); { let r = invariant.foo(); // compiler can''t shorten lifetime of `Invariant` // thus `invariant` is borrowed for `''long` lifetime } // Error. invariant is still borrowed here //invariant = Invariant(Cell::new(&val)); }

Enlace de juegos

Recientemente tuve un error que simplemente se resolvió cambiando

impl<''a> Foo<''a> { fn foo(&''a self, path: &str) -> Boo<''a> { /* */ } }

a

impl<''a> Foo<''a> { fn foo(&self, path: &str) -> Boo { /* */ } }

lo cual no tenía sentido de acuerdo a mi comprensión, ya que pensé que la segunda versión es exactamente la misma que la primera con la elisión de por vida aplicada.

En caso de que introduzcamos una nueva vida para el método, este parece ser el caso de acuerdo con este ejemplo del nomicon .

fn get_mut(&mut self) -> &mut T; // elided fn get_mut<''a>(&''a mut self) -> &''a mut T; // expanded

Entonces, ¿cuáles son las diferencias entre este y mi primer código recortado.