【发布时间】:2021-06-10 08:14:32
【问题描述】:
我正在使用两个独立的函数。
- 第一个获取结构的拥有实例,然后返回它。
- 第二个采用可变引用,但需要使用第一个函数。
// 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);
}
这段代码是否正确?如果没有,有没有办法安全地做到这一点?
【问题讨论】:
-
AFAIK 的主要问题是
take_owned可能会发生恐慌,在这种情况下,无论您在调用者内部做什么,所有权都不会被返回。 -
啊,是的。那么使用
std::panic::catch_unwind之类的东西会解决问题吗?