如何在循环中使用可变状态?
循环:
impl State {
pub fn exec(&mut self) -> Vec<(&[u8], SocketAddr)> {
vec!()
}
}
fn main_loop(mut state: State) {
let mut packets = Vec::<(&[u8], SocketAddr)>::new();
loop {
let new = state.exec();
packets.extend(new);
}
}
给出错误:
error[E0499]: cannot borrow `state` as mutable more than once at a time
--> src/main.rs:93:14
|
93 | let new = state.exec();
| ^^^^^ `state` was mutably borrowed here in the previous iteration of the loop
但是,如果我注释掉该packets.extend(new);行,则没有错误。
我认为问题在于返回的向量由 拥有state,就像new在循环迭代之前被丢弃一样,这很好。如果可以修复它,我很高兴复制返回的向量。
我预计增加.clone()要么new或state.exec()将有固定的,但事实并非如此。
有没有简单的方法来解决这个问题?
或者我是否需要以不同的方式构建单线程应用程序状态?
回答
pub fn exec(&mut self) -> Vec<(&[u8], SocketAddr)>
让我们添加隐式生命周期
pub fn exec<'a>(&'a mut self) -> Vec<(&'a [u8], SocketAddr)>
因此返回的切片必须与可变借用具有相同的生命周期。现在,你如何处理返回的切片?
let new = state.exec();
packets.extend(new);
我们将其存储在packets. 所以借用state必须至少与 的类型一样长packets,这就是整个函数。因此,从循环的第一次迭代到函数的最后,我们永远不能state再次借用,因为可变借用一直持续到函数结束。
要问自己的第一个问题是:您真的需要可变借用吗?如果你能做到&self,那么就这样做,你的问题就解决了。否则,您将需要以某种方式重组事物。该类型&[u8]本质上是无主的。这是对别人数据的引用。如果您必须通过 获取该数据的唯一方法&mut self,那么您将永远无法按照您想要的方式进行循环。因此,克隆数据,你需要使用to_vec,其轮流&[u8]到Vec<u8>(你的类型签名将不得不改变,以反映这一点)。