这个问题很简单,但是我不知道如何在Rust中实现它:
我有一个等待新客户端连接的TCP服务器。每个Client
分别存储TCPStream
和UUID
,并存储在ClientHolder
结构中。该结构实现了一个update
函数,该函数将为每个Client::update
调用Client
。
Client::update
函数如下所示:
pub fn update(&mut self) -> bool {
let mut msg = String::new();
match self.bufreader.read_line(&mut msg) {
Ok(size) => {
if size > 1 {
self.parse(&msg);
}
true
}
Err(_) => {
println!(
"Terminating connection with {}",self.stream.peer_addr().unwrap()
);
self.stream.shutdown(Shutdown::Both).unwrap();
false
}
}
}
我需要parse
函数才能执行将修改客户端的代码(例如,将命令从客户端传输到另一个客户端)。我找不到在不触发无法修复的借用或生命周期错误的情况下从parse
函数内部获取对客户的引用的方法。
如果有人能指出我正确的方向,我将不胜感激。我在这个问题上苦苦挣扎了两天,尝试了很多事情。
编辑:
这是parse
的示例:
fn parse(&mut self,msg: &String,holder: &ClientHolder) {
let v: Value = serde_json::from_str(&msg).unwrap();
if v["type"] == "init" {
self.set_uuid(v["uuid"].to_string());
}
else {
let uuid = v["uuid"];
let client = holder.get_client(&uuid);
command_service.try_execute(v["type"],client);
}
}
如果使用更新转发&ClientHolder
,则会发生以下情况:
在ClientHolder
内,update
函数调用Client::update
并传递self
的不变引用。如果客户端断开连接,则会将其从Vec
中删除。
pub fn update(&mut self) {
for i in (0..self.clients.len()).rev() {
let client = &mut self.clients[i];
if !client.update(&*self) {
self.clients.swap_remove(i);
}
}
}
编译器给我这个错误:
error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
--> src\server\client_holder.rs:25:31
|
24 | let client = &mut self.clients[i];
| ------------ mutable borrow occurs here
25 | if !client.update(&*self) {
| ------ ^^^^^^ immutable borrow occurs here
| |
| mutable borrow later used by call
我知道为什么会这样,但是找不到适合我的解决方案。