Ich schreibe einen Code in Rust, der eine Verbindung zu einem Remote-Server herstellt und je nach den von diesem Server gesendeten Nachrichten einige Statistiken berechnet oder Aktionen basierend auf diesen Statistiken ausführt. Aber das ist eher ein Lernprojekt für mich und ich bin auf ein Problem gestoßen.Bearbeiten eines Objekts aus einer Schleife, die es ausborgt
Hier ist der Code, den ich auf ein Minimum reduziert haben, das Problem zu reproduzieren:
// 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");
}
Während ich glaube, ich verstehe, warum der Compiler unglücklich ist, ich bin zu kämpfen mit einer Lösung zu kommen. Ich kann meine Struktur außerhalb der Schleife nicht manipulieren, da ich arbeiten muss, während ich verbunden bin und dem Server zuhöre. Ich könnte auch alles direkt in die Schleife schreiben und keine Methode aufrufen, aber ich möchte nicht mit einer 1000-Zeilen-Schleife enden (und ich würde lieber verstehen, wie eine tatsächliche Lösung aussehen würde).
Interessant. Meine erste, obwohl Sie Ihren ersten Vorschlag gelesen hatte, war, dass ich den gleichen Fehler bekommen würde, weil ein mut ref auf 'self.state' zu rufen process_message würde versuchen, eine mut ref von' selbst zu bekommen, aber Ihr Beispiel funktioniert in der Tat .. . Ich bin mir nicht sicher warum! Ich denke, das bedeutet, ich sollte ein wenig mehr über das Ausleihen von – Shtong
lesen Sie können Felder der Struktur separat ausleihen; Das erste Dokument, das ich gefunden habe, ist https://doc.rust-lang.org/nomicon/borrow-splitting.html –