Я пишу код в Rust, который подключается к удаленному серверу, и в зависимости от сообщений, отправленных этим сервером, вычисляет некоторую статистику или выполняет действия на основе этих статистических данных. Но для меня это скорее учебный проект, и я столкнулся с проблемой.
Вот код, который я уменьшил до минимума, чтобы воспроизвести проблему:
// Repro code for error[E0502]: cannot borrow `*self` as mutable because `self.server` is also borrowed as immutable
use std::collections::HashMap;
struct ServerReader {
server: Vec<u32>, // A vec for demo purposes, but please imagine this is a server object
counters: HashMap<u32, usize>,
}
impl ServerReader {
fn new() -> ServerReader {
ServerReader {
server: vec!(1, 2, 5, 2, 7, 9, 1, 1, 5, 6), // Filling my "server" with some messages
counters: HashMap::new(),
}
}
fn run(&mut self) {
println!("Connecting..."); // ... here there should be some code to connect to the server ...
for message in self.server.iter() { // We wait for the network messages sent by the server, and process them as they come
// ----------- immutable borrow occurs here
println!("Received {}", message);
self.process_message(*message); // HOW
// ^^^^ mutable borrow occurs here
}
// - immutable borrow ends here
println!("Disconnected");
}
fn process_message(&mut self, message: u32) {
// Please imagine that this function contains complex stuff
let counter = self.counters.entry(message).or_insert(0);
*counter += 1;
}
}
fn main() {
let mut reader = ServerReader::new();
reader.run();
println!("Done");
}
Хотя я думаю, что понимаю, почему компилятор несчастлив, я изо всех сил пытаюсь найти решение. Я не могу манипулировать своей структурой за пределами цикла, поскольку мне приходится работать при подключении и прослушивании сервера. Я также мог бы поставить все непосредственно в цикле и не вызывать какой-либо метод, но я не хочу заканчивать 1000-строчным циклом (и я бы предпочел понять, как будет выглядеть фактическое решение).