是否有一种安全的方法可以从Rust中的可变引用临时检索所拥有的值?

是否有一种安全的方法可以从Rust中的可变引用临时检索所拥有的值?,rust,unsafe,ownership,Rust,Unsafe,Ownership,我正在使用两个独立的函数 第一个实例获取结构的一个拥有的实例,然后返回它。 第二个函数接受可变引用,但需要使用第一个函数。 我想了一个解决方案,但我不确定它是否合理: 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) ->

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

第一个实例获取结构的一个拥有的实例,然后返回它。 第二个函数接受可变引用,但需要使用第一个函数。 我想了一个解决方案,但我不确定它是否合理:

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

这个密码正确吗?如果没有,有没有办法安全地执行此操作?

有人已经在名为的板条箱中实现了您要查找的内容

函数take_mut::take 发布fn takemut_ref:&mut T T,结束:F 哪里 F:fnonset->T, 允许使用由&mut T指向的值,就好像它是拥有的一样,只要T之后可用

如果关闭中断,将中止程序

函数take_mut::take_或_recover 发布fn take_或recovermut_ref:&mut T T,recover:R,closure:F 哪里 F:fnonset->T, R:FNOCE->T, 允许使用由&mut T指向的值,就好像它是拥有的一样,只要T之后可用

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


实现基本上就是您所拥有的,再加上所描述的紧急处理。

有人已经在名为

函数take_mut::take 发布fn takemut_ref:&mut T T,结束:F 哪里 F:fnonset->T, 允许使用由&mut T指向的值,就好像它是拥有的一样,只要T之后可用

如果关闭中断,将中止程序

函数take_mut::take_或_recover 发布fn take_或recovermut_ref:&mut T T,recover:R,closure:F 哪里 F:fnonset->T, R:FNOCE->T, 允许使用由&mut T指向的值,就好像它是拥有的一样,只要T之后可用

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


实现基本上就是您所拥有的,再加上所描述的恐慌处理。

AFAIK的主要问题是take_owned可能会恐慌,在这种情况下,无论您在调用方内部做什么,都不会返回所有权。啊,是的。那么,使用类似的方法解决问题吗?AFAIK的主要问题是take_owned可能会引起恐慌,在这种情况下,所有权永远不会被归还,无论你在呼叫方内部做什么。啊,是的。那么,使用类似的方法解决问题吗?
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);
}