如何将一个字段移出实现 Drop trait 的结构? [英] How to move one field out of a struct that implements Drop trait?

查看:67
本文介绍了如何将一个字段移出实现 Drop trait 的结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个无效的 Rust 程序(Rust 1.1 版),其函数执行 HTTP 客户端请求并仅返回标头,丢弃响应中的所有其他字段.

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());
}

以下是编译器错误:

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 成员.

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.

我的问题是:我怎样才能解决这个问题并且仍然拥有良好的安全 Rust 代码?我知道我可以通过 clone() 进行复制,如下所示:

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()),

但是,来自 C++,这似乎效率低下.移动就足够了,为什么要复制?我设想在 C++ 中执行类似以下操作以强制调用移动构造函数(如果可用):

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);

有没有办法在 Rust 中放弃 copy 而是强制 move,类似于 C++?

Is there any way to forgo the copy in Rust and instead force a move, similar to C++?

推荐答案

您可以使用 std::mem::replace() 用新的空白值交换字段以将所有权转让给您:

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());
}

在这里,我们用一组新的空标头替换 response.headers.replace() 返回在我们替换它之前存储在字段中的值.

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.

这篇关于如何将一个字段移出实现 Drop trait 的结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆