¿Por qué es legal pedir prestado un temporal?
Viniendo de C++, me sorprende bastante que este código sea válido en Rust:
let x = &mut String::new();
x.push_str("Hello!");
En C++, no se puede tomar la dirección de un temporal, y un temporal no sobrevivirá a la expresión en la que aparece.
¿Cuánto tiempo vive el temporal en Rust? Y como x
es sólo un préstamo, ¿quién es el dueño de la cadena?
¿Por qué es legal pedir prestado un temporal?
Es legal por la misma razón que es ilegal en C++: porque alguien dijo que así debería ser .
¿Cuánto tiempo vive el temporal en Rust? Y como
x
es sólo un préstamo, ¿quién es el dueño de la cadena?
La referencia dice :
el alcance temporal de una expresión es el alcance más pequeño que contiene la expresión y es para uno de los siguientes:
- Todo el cuerpo funcional.
- Una declaración.
- El cuerpo de a
if
owhile
expresiónloop
.- El
else
bloque de unaif
expresión.- La expresión de condición de una expresión
if
owhile
, o unmatch
guardia.- La expresión para un brazo de cerilla.
- El segundo operando de una expresión booleana diferida .
Básicamente, puedes tratar tu código como:
let mut a_variable_you_cant_see = String::new();
let x = &mut a_variable_you_cant_see;
x.push_str("Hello!");
Ver también:
- ¿Por qué puedo devolver una referencia a un literal local pero no a una variable?
- ¿Cuál es el alcance de los valores sin nombre?
- ¿Están bien los punteros sin formato a los temporales en Rust?
De la referencia de Rust :
Vidas temporales
Cuando se utiliza una expresión de valor en la mayoría de los contextos de expresión de lugar, se crea una ubicación de memoria temporal sin nombre inicializada con ese valor y la expresión se evalúa en esa ubicación.
Esto se aplica porque String::new()
es una expresión de valor y al estar justo debajo &mut
está en un contexto de expresión de lugar. Ahora el operador de referencia solo tiene que pasar por esta ubicación de memoria temporal, por lo que se convierte en el valor de todo el lado derecho (incluido &mut
).
Sin embargo, cuando se crea una expresión de valor temporal que se asigna a una declaración let, el temporal se crea con la vida útil del bloque adjunto.
Dado que está asignado a la variable, tiene una vida útil hasta el final del bloque adjunto.
Esto también responde a esta pregunta sobre la diferencia entre
let a = &String::from("abcdefg"); // ok!
y
let a = String::from("abcdefg").as_str(); // compile error
En la segunda variante, el temporal se pasa a as_str()
, por lo que su duración finaliza al final de la declaración.