微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有一种安全的方法可以从 Rust 的可变引用中临时检索一个拥有的值? 函数take_mut::take函数take_mut::take_or_recover

如何解决有没有一种安全的方法可以从 Rust 的可变引用中临时检索一个拥有的值? 函数take_mut::take函数take_mut::take_or_recover

我正在使用两个独立的函数

  • 一个获取结构的拥有实例,然后返回它。
  • 第二个接受可变引用但需要使用第一个函数
// This structure is not `Clone`.
struct MyStruct;

fn take_owned(s: MyStruct) -> MyStruct {
    // Do things
    s
}

fn take_mut(s: &mut MyStruct) {
    *s = take_owned(s /* problem */);
}

我想到了一个解决方案,但我不确定它是否合理:

use std::ptr;

// Temporarily turns a mutable reference into an owned value.
fn mut_to_owned<F>(val: &mut MyStruct,f: F)
where
    F: FnOnce(MyStruct) -> MyStruct,{
    // We're the only one able to access the data referenced by `val`.
    // This operation simply takes ownership of the value.
    let owned = unsafe { ptr::read(val) };

    // Do things to the owned value.
    let result = f(owned);

    // Give the ownership of the value back to its original owner.
    // From its point of view,nothing happened to the value because we have
    // an exclusive reference.
    unsafe { ptr::write(val,result) };
}

使用这个功能,我可以做到:

fn take_mut(s: &mut MyStruct) {
    mut_to_owned(s,take_owned);
}

这段代码好听吗?如果没有,有没有办法安全地做到这一点?

解决方法

有人已经在名为 take_mut 的板条箱中实现了您正在寻找的东西。

函数take_mut::take

pub fn take<T,F>(mut_ref: &mut T,closure: F) 
where
    F: FnOnce(T) -> T,

允许使用 &mut T 指向的值,就好像它是拥有的一样,只要 T 之后可用。

...

如果闭包崩溃,将中止程序。

函数take_mut::take_or_recover

pub fn take_or_recover<T,F,R>(mut_ref: &mut T,recover: R,R: FnOnce() -> T,

允许使用 &mut T 指向的值,就好像它是拥有的一样,只要 T 之后可用。

...

如果 &mut T 恐慌,将用 recover 替换 closure,然后继续恐慌。

实现本质上就是你所拥有的,加上所描述的恐慌处理。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。