暂时搬出借来的内容 [英] Temporarily move out of borrowed content
问题描述
我正在尝试替换可变借用中的值;将它的一部分移动到新值中:
I'm tring to replace a value in a mutable borrow; moving part of it into the new value:
enum Foo<T> {
Bar(T),
Baz(T),
}
impl<T> Foo<T> {
fn switch(&mut self) {
*self = match self {
&mut Foo::Bar(val) => Foo::Baz(val),
&mut Foo::Baz(val) => Foo::Bar(val),
}
}
}
上面的代码不起作用,可以理解的是,将值移出 self
会破坏它的完整性.但由于该值随后立即被删除,我(如果不是编译器)可以保证它的安全性.
The code above doesn't work, and understandibly so, moving the value out of self
breaks the integrity of it. But since that value is dropped immediately afterwards, I (if not the compiler) could guarantee it's safety.
有什么方法可以实现这一目标吗?我觉得这是不安全代码的工作,但我不确定它会如何工作.
Is there some way to achieve this? I feel like this is a job for unsafe code, but I'm not sure how that would work.
推荐答案
好的,我想出了如何用一点unsafe
ness 和 std::mem
.
Okay, I figured out how to do it with a bit of unsafe
ness and std::mem
.
我用一个未初始化的临时值替换了 self
.由于我现在拥有"过去的 self
,我可以安全地将值移出它并替换它:
I replace self
with an uninitialized temporary value. Since I now "own" what used to be self
, I can safely move the value out of it and replace it:
use std::mem;
enum Foo<T> {
Bar(T),
Baz(T),
}
impl<T> Foo<T> {
fn switch(&mut self) {
// This is safe since we will overwrite it without ever reading it.
let tmp = mem::replace(self, unsafe { mem::uninitialized() });
// We absolutely must **never** panic while the uninitialized value is around!
let new = match tmp {
Foo::Bar(val) => Foo::Baz(val),
Foo::Baz(val) => Foo::Bar(val),
};
let uninitialized = mem::replace(self, new);
mem::forget(uninitialized);
}
}
fn main() {}
这篇关于暂时搬出借来的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!