Я работаю с двумя отдельными функциями.
- Первый берет принадлежащий экземпляр структуры, а затем возвращает его.
- Второй принимает изменяемую ссылку, но должен использовать первую функцию.
// 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_owned
может паниковать, и в этом случае право собственности никогда не будет возвращено, что бы вы ни делали внутри вызывающего абонента. - person Cerberus   schedule 12.03.2021std::panic::catch_unwind
? - person Gymore   schedule 12.03.2021