这是一个无效的 Rust 程序(Rust 版本 1.1),其函数执行 HTTP 客户端请求并仅返回 header ,丢弃响应中的所有其他字段。
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());
}
这里是编译错误:
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
我明白为什么借用检查器不接受这个程序——也就是说,drop
函数将在它接受之后使用response
移动了它的 headers
成员。
我的问题是:我怎样才能解决这个问题并仍然拥有安全的 Rust 代码?我知道我可以通过 clone()
进行复制,如下所示:
Ok(response) => Ok(response.headers.clone()),
但是,来自 C++,这似乎效率低下。当移动 就足够时,为什么要复制?我设想在 C++ 中执行类似以下操作以强制调用移动构造函数(如果可用):
headers_to_return = std::move(response.headers);
有什么方法可以在 Rust 中放弃复制,而是强制执行移动,类似于 C++?
最佳答案
您可以使用 std::mem::replace()
用新的空白值交换该字段,以便将所有权转让给您:
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());
}
在这里,我们用一组新的空 header 替换 response.headers
。 replace()
返回替换前存储在字段中的值。
关于rust - 如何将一个字段移出实现 Drop 特性的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31307680/