我的网络应用程序的架构可以简化为以下内容:
use std::collections::HashMap;
/// Represents remote user. Usually has fields,
/// but we omit them for the sake of example.
struct User;
impl User {
/// Send data to remote user.
fn send(&mut self, data: &str) {
println!("Sending data to user: \"{}\"", data);
}
}
/// A service that handles user data.
/// Usually has non-trivial internal state, but we omit it here.
struct UserHandler {
users: HashMap<i32, User>, // Maps user id to User objects.
counter: i32 // Represents internal state
}
impl UserHandler {
fn handle_data(&mut self, user_id: i32, data: &str) {
if let Some(user) = self.users.get_mut(&user_id) {
user.send("Message received!");
self.counter += 1;
}
}
}
fn main() {
// Initialize UserHandler:
let mut users = HashMap::new();
users.insert(1, User{});
let mut handler = UserHandler{users, counter: 0};
// Pretend we got message from network:
let user_id = 1;
let user_message = "Hello, world!";
handler.handle_data(user_id, &user_message);
}
这个可以正常工作。我想在 UserHandler
中创建一个单独的方法,用于处理已经确认存在具有给定 id 的用户输入。因此它变成了:
impl UserHandler {
fn handle_data(&mut self, user_id: i32, data: &str) {
if let Some(user) = self.users.get_mut(&user_id) {
self.handle_user_data(user, data);
}
}
fn handle_user_data(&mut self, user: &mut User, data: &str) {
user.send("Message received!");
self.counter += 1;
}
}
突然间,它不能编译了!
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> src/main.rs:24:13
|
23 | if let Some(user) = self.users.get_mut(&user_id) {
| ---------- first mutable borrow occurs here
24 | self.handle_user_data(user, data);
| ^^^^ ---- first borrow later used here
| |
| second mutable borrow occurs here
乍一看,错误非常明显:您不能同时拥有对 `self` 可变引用和其属性的可变引用——这就像同时拥有两个对 `self` 的可变引用。但是,在原始代码中,我确实像这样拥有了两个可变引用!
- 为什么这个简单的重构会触发借用检查器错误?
- 如何解决这个问题并将 `UserHandler::handle_data` 方法分解成以下形式?
如果你想知道我为什么想要这样的重构,请考虑这样一个情况:用户可能发送多种类型的消息,需要分别处理,但有一个公共部分:需要知道发送此消息的 `User` 对象。