相关疑难解决方法(0)

如何从实现Drop trait的结构中移出一个字段?

这是一个无效的Rust程序(Rust版本1.1),其中包含一个执行HTTP客户端请求的函数,只返回标题,删除响应中的所有其他字段.

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());
}
Run Code Online (Sandbox Code Playgroud)

以下是编译器错误:

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
Run Code Online (Sandbox Code Playgroud)

我理解为什么借用检查器不接受这个程序 - 即,该drop函数将response在其headers成员被移动之后使用它.

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

Ok(response) => Ok(response.headers.clone()), …
Run Code Online (Sandbox Code Playgroud)

rust

23
推荐指数
1
解决办法
3654
查看次数

mem :: forget(mem :: uninitialized())定义的行为是什么?

mutagen中,我在代码中注入了各种突变.我想改变的一件事是模式 if let Ok(x) = y { .. }.然而,这构成了相当大的挑战,因为我无法知道其类型y- 用户可以使用一元Ok变体构建自己的枚举.我仍然可以机会性地改变它,因为我们实际上有一个Result错误类型实现的情况Default使用类似于以下简化的特征:

#![feature(specialization)]

pub trait Errorer {
    fn err(self, mutate: bool) -> Self;
}

impl<X> Errorer for X {
    default fn err(self, _mutate: bool) -> Self {
        self
    }
}

impl<T, E> Errorer for Result<T, E>
where
    E: Default,
{
    fn err(self, mutate: bool) -> Self {
        if mutate {
            Err(Default::default())
        } else {
            self
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

唉,实现的错误并不多Default,所以这不太有用.即使是实现 …

unsafe undefined-behavior rust

12
推荐指数
1
解决办法
227
查看次数

如何在不丢弃对象的情况下解构对象?

我有一个结构,我想按值获取、变异然后返回。我还想改变它的泛型类型,因为我使用此状态静态地确保函数调用的正确顺序,以实现安全的 FFI(游乐场):

use core::marker::PhantomData;

struct State1 {}
struct State2 {}
struct Whatever {}

struct X<State> {
    a: Whatever,
    b: Whatever,
    c: Whatever,
    _d: PhantomData<State>,
}

impl<State> Drop for X<State> {
    fn drop(&mut self) {}
}

fn f(x: X<State1>) -> X<State2> {
    let X { a, b, c, _d } = x;
    //mutate a, b and c
    X {
        a,
        b,
        c,
        _d: PhantomData,
    } // return new instance
}
Run Code Online (Sandbox Code Playgroud)

因为X实现了Drop,我得到:

use core::marker::PhantomData;

struct State1 …
Run Code Online (Sandbox Code Playgroud)

ownership rust borrow-checker drop

7
推荐指数
2
解决办法
2448
查看次数

暂时离开借来的内容

我想在可变借入中替换一个值; 将其中的一部分移动到新值中:

enum Foo<T> {
    Bar(T),
    Baz(T),
}

impl<T> Foo<T> {
    fn switch(&mut self) {
        *self = match self {
            &mut Foo::Bar(val) => Foo::Baz(val),
            &mut Foo::Baz(val) => Foo::Bar(val),
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码不起作用,并且可以理解的是,将值移出会self破坏它的完整性.但由于之后立即删除了该值,我(如果不是编译器)可以保证它的安全性.

有没有办法实现这个目标?我觉得这是一个不安全代码的工作,但我不确定这是如何工作的.

ownership rust borrow-checker

5
推荐指数
3
解决办法
1184
查看次数