par*_*tic 5 swap struct reference rust
我开始研究Rust,我正在尝试实现一个简单的一维元胞自动机.我想将自动机状态(Board)表示为包含大小和两个不同向量(相同大小)的结构.我试过了:
struct Board {
n: usize,
cur: Vec<u32>,
next: Vec<u32>,
}
impl Board {
fn new(size: usize) -> Board {
Board {
n: size,
cur: vec![0;size],
next: vec![0;size],
}
}
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.我也能够改变两种载体.但后来我希望能够交换两个向量(或者更确切地说是它们的引用),例如:
fn swap(&mut self) -> &Board {
let tmp = self.cur;
self.cur = self.next;
self.next = tmp;
self
}
Run Code Online (Sandbox Code Playgroud)
它失败了cannot move out of borrowed content [E0507],我想我能理解.我也尝试了mem::swap在类似的标题问题中找到的但没有成功.
我怎样才能使这个例子有效?(因为我是Rust的初学者,所以请不要犹豫,建议不同的数据表示).
有什么问题?
您正在对数据打孔:
fn swap(&mut self) -> &Board {
let tmp = self.cur; // 1
self.cur = self.next; // 2
self.next = tmp; // 3
self
}
Run Code Online (Sandbox Code Playgroud)
如果我们逐行分析:
self.cur 现在尚未初始化self.next 现在尚未初始化如果出于某种原因,在第(3)行进行更改以加强这种情况之前中断了计算,self则该操作现在中毒了,并可能导致各种令人讨厌的事情发生。值得注意的是,它的析构函数可能会尝试两次释放内存。
从理论上讲,您可以让编译器检查临时漏洞并毫无疑问地证明:
self打孔时无法使用任何功能确实在某个时候已经考虑过了……但是事实是它很复杂,并且随时都有解决方法。
所以?
答案在于std::mem公开功能以安全的方式执行此类低级操作。虽然功能本身是unsafe在幕后使用的,但它们依靠对语言和运行时的理解来公开安全的接口。
您会感兴趣的两个特定功能是:
replace:替换dest: &mut Tby 的内容src: T并返回之前包含的内容destswap:交换其参数的内容使用这两个简单且安全的原语,您可以避免在数据中打孔。
正如您所注意到的,mem::swap要走的路是:
fn swap(&mut self) -> &Board {
std::mem::swap(&mut self.cur, &mut self.next);
self
}
Run Code Online (Sandbox Code Playgroud)
这有效。请注意,使用时.您正在解除引用self。所以既有self型&mut Board,self.cur就有型Vec<u32>。因此,编译器抱怨“移出借用的内容”,我们需要额外的&muts。
| 归档时间: |
|
| 查看次数: |
351 次 |
| 最近记录: |