Here's an invalid Rust program (Rust version 1.1) with a function that does an HTTP client request and returns only the headers, dropping all other fields in the response.
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()); }
Here are the compiler errors:
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
I understand why the borrow checker doesn't accept this program—i.e., that the drop
function will use the response
after it has had its headers
member moved.
My question is: How can I get around this and still have good safe Rust code? I know I can do a copy, via clone()
, like so:
Ok(response) => Ok(response.headers.clone()),
But, coming from C++, that seems inefficient. Why copy when a move should suffice? I envision in C++ doing something like the following to force a call to a move constructor, if available:
headers_to_return = std::move(response.headers);
Is there any way to forgo the copy in Rust and instead force a move, similar to C++?
You can use std::mem::replace()
to swap the field with a new blank value in order to transfer ownership to you:
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(mut response) => Ok(std::mem::replace(&mut response.headers, hyper::header::Headers::new())), } } fn main() { println!("{:?}", just_the_headers()); }
Here, we're replacing response.headers
with a new empty set of headers. replace()
returns the value that was stored in the field before we replaced it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With