rust - Vinculando las vidas de uno mismo y una referencia en el método
(1)
En la llamada al método
set
, se usa el parámetro de vida útil en el bloque implícito y la vida útil del valor dew
se completa para''a
en la firma del método.
No. El valor del parámetro de vida útil
''a
se fija en la creación de la estructura
Foo
, y nunca cambiará ya que es parte de su tipo.
En su caso, el compilador realmente elige
''a
un valor que sea compatible con las vidas de
v
y
w
.
Si eso no fuera posible, fallaría, como en este ejemplo:
fn main() {
let v = 5;
let mut f = Foo { x: &v };
println!("f is {:?}", f);
let w = 7;
f.set(&w);
println!("now f is {:?}", f);
}
que salidas:
error[E0597]: `w` does not live long enough
--> src/main.rs:21:1
|
18 | f.set(&w);
| - borrow occurs here
...
21 | }
| ^ `w` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
Exactamente porque la vida impuesta por
v
no es compatible con la vida útil más corta de
w
.
En el segundo ejemplo, al forzar la vida del
self
a ser
''a
también'', está vinculando el préstamo mutable a la vida
''a
también, y así el préstamo termina cuando todos los elementos de la vida
''a
quedan fuera de alcance, a saber
v
y
w
.
Tengo este pedazo de código :
#[derive(Debug)]
struct Foo<''a> {
x: &''a i32,
}
impl<''a> Foo<''a> {
fn set(&mut self, r: &''a i32) {
self.x = r;
}
}
fn main() {
let v = 5;
let w = 7;
let mut f = Foo { x: &v };
println!("f is {:?}", f);
f.set(&w);
println!("now f is {:?}", f);
}
Según tengo entendido, en el primer préstamo del valor de
v
, el parámetro de vida genérico
''a
en la declaración de estructura se completa con la vida útil del valor de
v
.
Esto significa que el objeto
Foo
resultante no debe vivir más tiempo que esto
''a
toda
''a
vida o que el valor de
v
debe vivir al menos tanto como el objeto
Foo
.
En la llamada al
set
métodos, se utiliza el parámetro de vida útil en el bloque
impl
y la vida útil del valor de
w
se completa para
''a
en la firma del método.
&mut self
compilador asigna una vida diferente a
&mut self
, que es la vida útil de
f
(el objeto
Foo
).
Si cambiara el orden de los enlaces de
w
y
f
en la función
main
, esto resultaría en un error.
Me preguntaba qué pasaría si
&mut self
referencia
&mut self
con el mismo parámetro de vida útil
''a
as
r
en el método
set
:
impl<''a> Foo<''a> {
fn set(&''a mut self, r: &''a i32) {
self.x = r;
}
}
Lo que resulta en el siguiente error:
error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
--> src/main.rs:21:31
|
19 | f.set(&w);
| - mutable borrow occurs here
20 |
21 | println!("now f is {:?}", f);
| ^ immutable borrow occurs here
22 | }
| - mutable borrow ends here
En contraste con el ejemplo anterior,
f
todavía se considera prestado de manera mutable para cuando se imprime la segunda.
se llama, por lo que no puede ser prestado simultáneamente como inmutable.
¿Cómo llegó a ser esto?
Al no dejar de lado la anotación de por vida, el compilador completó uno para mí
&mut self
para
&mut self
en el primer ejemplo.
Esto sucede según las reglas de elisión de por vida.
Sin embargo, al establecerlo explícitamente en
''a
en el segundo ejemplo, vinculé las vidas del valor de
f
y el valor de
w
.
¿Se considera
f
prestado por sí mismo de alguna manera?
Y si es así, ¿cuál es el alcance del préstamo?
¿Es min (vida útil de
f
, vida útil de
w
) -> vida útil de
f
?
Supongo que todavía no he entendido completamente la referencia
&mut self
en la llamada a la función.
Quiero decir, la función regresa, pero
f
todavía se considera prestada.
Estoy tratando de entender completamente las vidas. Principalmente busco comentarios correctivos sobre mi comprensión de los conceptos. Estoy agradecido por cada pequeño consejo y más aclaraciones.