¿Por qué el valor se traslada al cierre aquí en lugar de ser prestado?
losCapítulo de manejo de errores del Rust Book contiene un ejemplo sobre cómo usar los combinadores deOption
yResult
. Se lee un archivo y, mediante la aplicación de una serie de combinadores, los contenidos se analizan comoi32
y regresó en unResult<i32, String>
. Ahora, me confundí cuando miré el código. Allí, en un cierre a un y luego un localString
Se crea un valor que luego se pasa como valor de retorno a otro combinador.
Aquí está el ejemplo de código:
use std::fs::File;
use std::io::Read;
use std::path::Path;
fn file_double<P: AsRef<Path>>(file_path: P) -> Result<i32, String> {
File::open(file_path)
.map_err(|err| err.to_string())
.and_then(|mut file| {
let mut contents = String::new(); // local value
file.read_to_string(&mut contents)
.map_err(|err| err.to_string())
.map(|_| contents) // moved without 'move'
})
.and_then(|contents| {
contents.trim().parse::<i32>()
.map_err(|err| err.to_string())
})
.map(|n| 2 * n)
}
fn main() {
match file_double("foobar") {
Ok(n) => println!("{}", n),
Err(err) => println!("Error: {}", err),
}
}
El valor al que me refiero escontents
. Se crea y luego se hace referencia en elmap
combinador aplicado a lastd::io::Result<usize>
valor de retorno deRead::read_to_string
. La pregunta: pensé queno marcando el cierre conmove
tomaría prestado cualquier valor referenciado por defecto, lo que resultaría en que el verificador de préstamos se queje, quecontents
no vive lo suficiente Sin embargo, este código se compila muy bien. Eso significa que elString
contents
se mueve dentro, y con frecuencia fuera del cierre. ¿Por qué se hace esto sin lo explícito?move
?