Warum wird der Wert hier in die Schließung verschoben und nicht ausgeliehen?
Dasapitel "Fehlerbehandlung&quo des Rust-Buches enthält ein Beispiel für die Verwendung der Kombinatoren vonOption
undResult
. Eine Datei wird gelesen und durch Anwendung einer Reihe von Kombinatoren wird der Inhalt als @ analysieri32
und in einem @ zurückgegebResult<i32, String>
. Jetzt war ich verwirrt, als ich mir den Code ansah. Dort wird in einem Closure ein und_dann ein lokalesString
value wird erstellt und anschließend als Rückgabewert an einen anderen Combinator übergeben.
Hier ist das Codebeispiel:
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),
}
}
Der Wert, auf den ich mich beziehe, istcontents
. Es wird erstellt und später im @ referenziermap
combinator angewendet auf dasstd::io::Result<usize>
Rückgabewert vonRead::read_to_string
. Die Frage: Ich dachte, dassnich markiere den Verschluss mitmove
würde jeden referenzierten Wert standardmäßig ausleihen, was dazu führen würde, dass der Ausleihprüfer sich beschwert, dasscontents
lebt nicht lange genug. Dieser Code wird jedoch problemlos kompiliert. Das heißt, dasString
contents
wird in den Verschluss hinein und anschließend wieder heraus bewegt. Warum erfolgt dies ohne das explizitemove
?