Hier ist ein ungültiges Rust-Programm (Rust-Version 1.1) mit einer Funktion, die eine HTTP-Client-Anfrage ausführt und nur die Header zurückgibt und alle anderen Felder in der Antwort löscht.Wie verschiebt man ein Feld aus einer Struktur, die Drop-Eigenschaft implementiert?
extern crate hyper;
fn just_the_headers() -> Result<hyper::header::Headers, hyper::error::Error> {
let c = hyper::client::Client::new();
let result = c.get("http://www.example.com").send();
match result {
Err(e) => Err(e),
Ok(response) => Ok(response.headers),
}
}
fn main() {
println!("{:?}", just_the_headers());
}
Hier sind die Compiler-Fehler:
main.rs:8:28: 8:44 error: cannot move out of type `hyper::client::response::Response`, which defines the `Drop` trait
main.rs:8 Ok(response) => Ok(response.headers),
^~~~~~~~~~~~~~~~
error: aborting due to previous error
ich verstehen, warum die borrow checker dieses Programm nicht, dh nicht akzeptiert, dass die drop
Funktion der response
verwenden, nachdem er seine hatte headers
Mitglied verschoben.
Meine Frage ist: Wie kann ich das umgehen und habe immer noch guten sicheren Rust-Code? Ich weiß, ich kann über clone()
eine Kopie tun, etwa so:
Ok(response) => Ok(response.headers.clone()),
Aber, die aus C++, die ineffizient zu sein scheint. Warum kopieren, wenn ein move sollte ausreichen? Ich sehe in C++, etwas zu tun wie die nach einem Aufruf zu einem Umzug Konstruktor zu zwingen, falls vorhanden:
headers_to_return = std::move(response.headers);
Gibt es eine Möglichkeit, die Kopie in Rust zu verzichten und stattdessen zwingen, einen bewegen ähnlich C++?
Es kann nichts wert sein, dass 'std :: mem :: replace 'in Rust ist * mehr oder weniger * was' std :: move' in C++ ist. Da die Quelle und das Ziel gültig sein müssen, um sowohl vor als auch nach einer Bewegung zu zerstören, bewegt sich C++ nicht wirklich, es wird ausgetauscht. –
Mit dem Unterschied, dass in C++ die Klasse entscheidet, wie die Verschiebung implementiert wird (im Move-Konstruktor oder Move-Zuweisungsoperator), während "std :: mem :: replace" vom Aufrufer verlangt, einen geeigneten Wert anzugeben . Tatsächlich wird "std :: mem :: replace" in Form von "std :: mem :: swap" (http://doc.rust-lang.org/stable/std/mem/fn.swap) implementiert .html). –
Vielleicht möchten Sie bemerken, dass Rust auch auf extrem effiziente "Standardkonstrukte" Wert legt, zum Beispiel weder 'String :: new()' noch 'Vec :: new()' allokieren Speicher, was diese ersetzt als Effizient, da sich C++ zusätzlich sicherer verhält. –