有没有一种安全的方法可以从 Rust 中的可变引用中临时检索拥有的值?
Is there a safe way to temporarily retrieve an owned value from a mutable reference in Rust?
我正在使用两个独立的函数。
- 第一个接受结构的拥有实例,然后 returns 它。
- 第二个采用可变引用但需要使用第一个函数。
// 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
.
的 crate 中实现了您正在寻找的东西
Function take_mut::take
pub fn take<T, F>(mut_ref: &mut T, closure: F)
where
F: FnOnce(T) -> T,
Allows use of a value pointed to by &mut T
as though it was owned, as long as a T
is made available afterwards.
...
Will abort the program if the closure panics.
Function take_mut::take_or_recover
pub fn take_or_recover<T, F, R>(mut_ref: &mut T, recover: R, closure: F)
where
F: FnOnce(T) -> T,
R: FnOnce() -> T,
Allows use of a value pointed to by &mut T
as though it was owned, as long as a T
is made available afterwards.
...
Will replace &mut T
with recover
if the closure
panics, then continues the panic.
实施基本上就是您所拥有的,加上所描述的恐慌处理。
我正在使用两个独立的函数。
- 第一个接受结构的拥有实例,然后 returns 它。
- 第二个采用可变引用但需要使用第一个函数。
// 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
.
Function take_mut::take
pub fn take<T, F>(mut_ref: &mut T, closure: F) where F: FnOnce(T) -> T,
Allows use of a value pointed to by
&mut T
as though it was owned, as long as aT
is made available afterwards....
Will abort the program if the closure panics.
Function take_mut::take_or_recover
pub fn take_or_recover<T, F, R>(mut_ref: &mut T, recover: R, closure: F) where F: FnOnce(T) -> T, R: FnOnce() -> T,
Allows use of a value pointed to by
&mut T
as though it was owned, as long as aT
is made available afterwards....
Will replace
&mut T
withrecover
if theclosure
panics, then continues the panic.
实施基本上就是您所拥有的,加上所描述的恐慌处理。