Rust 如何在循环中使用可变状态?

Rust 如何在循环中使用可变状态?,rust,borrow-checker,Rust,Borrow Checker,循环: 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 = st

循环:

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);
    }
}
然而,如果我注释掉
packets.extend(new)行,没有错误

我认为问题在于返回的向量属于
state
,就好像
new
在循环迭代之前就被删除了一样,没有问题。我很高兴能够复制返回的向量,如果这样可以修复它的话

我原以为将
.clone()
添加到
new
state.exec()
会修复它,但它没有

有没有简单的方法来解决这个问题

或者我需要以不同的方式构造单线程应用程序状态吗?

一种解决方案是:

impl State {    
    pub fn exec(&mut self) -> Vec<(Vec<u8>, SocketAddr)> {
        vec!()
    }
}

fn main_loop(mut state: State) {
    let mut packets = Vec::<(Vec<u8>, SocketAddr)>::new();
    loop {
        let new = state.exec();
        packets.extend(new);
    }
}
impl状态{
发布fn exec(&mut self)->Vec{
vec!()
}
}
fn主回路(mut状态:状态){
让mut packets=Vec:::new();
环路{
让new=state.exec();
数据包。扩展(新);
}
}
我不确定这是否是最好的解决方案,因此我将把这个问题留待讨论

pub fn exec(&mut self) -> Vec<(&[u8], SocketAddr)>

我们将其存储在
数据包中。因此,
状态
的借用必须至少与
数据包类型
的借用时间相同,这是整个功能。因此,从循环的第一次迭代到函数的最后一次,我们再也不能借用
状态
,因为可变借用一直持续到函数的最后


要问自己的第一个问题是:你真的需要可变借款吗?如果你能认真地做
&self
,那么你的问题就解决了。否则,你将需要以某种方式重新构造事物。类型
和[u8]
本质上是无主的。这是对其他人数据的引用。如果获取数据的唯一方法是通过
&mut self
,那么您将永远无法按您想要的方式循环。因此,要克隆数据,您需要使用
to_vec
,这将
和[u8]
转换为
vec
(您的类型签名必须更改以反映这一点)。

只需更改函数签名,以便返回的
和[u8]
不会借用
*self
即可编译示例代码:

    pub fn exec<'a>(&mut self) -> Vec<(&'a [u8], SocketAddr)> {
        vec![]
    }
pub fn exec{
vec![]
}
请注意,
'a
是一个免费的生存期参数,因此调用者可以在那里提供任何内容(包括
'static
),而
exec
返回的任何引用都必须满足调用者提供的生存期。实际上,这意味着
Vec
只能包含
'静态
引用,因为
'静态
是唯一一个每隔一个生存期的子类型的生存期


这不可能是你想要的。但是,它可能是,或者
[u8]
可能是从其他参数借用的(而不是
*self
),或者是从
*self
中包含的引用重新借用的。这表明,只需更改签名以更准确地表示输入和输出之间的生命周期关系,有时就可以在不做任何其他更改的情况下修复此类错误。

您可以尝试返回对向量的引用吗?@mousetail我认为任何引用,通过可变状态的方法返回,停止循环编译。我理解正确了吗?
exec
是否需要执行
&mut self
?你可以有两种不同的方法吗,一种是进行突变,另一种是返回切片,后者采用
&self
?谢谢,这是一个非常清楚的解释。通过实验,我发现问题出在
和[u8]
上。这就解释了为什么在这种情况下,“由于可变借用一直持续到函数结束”对于无可变借用也是一样的,也许这句话有误导性。使用不可变的循环内借用代码就可以了。谢谢,这增加了我的理解。默认生命周期并不总是我们所需要的。
pub fn exec<'a>(&'a mut self) -> Vec<(&'a [u8], SocketAddr)>
let new = state.exec();
packets.extend(new);
    pub fn exec<'a>(&mut self) -> Vec<(&'a [u8], SocketAddr)> {
        vec![]
    }