Не могу найти свой путь вокруг жизни и заимствования - PullRequest
0 голосов
/ 26 марта 2020

Эта проблема очень проста, но я не могу понять, как реализовать это в 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

Я понимаю, почему это так, но не смог найти решение, которое работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...