не может заимствовать `...` как изменяемый, потому что он также заимствован как неизменный - PullRequest
1 голос
/ 29 октября 2019

Используя следующий код:

use std::{
    io::{BufRead, BufReader},
    net::TcpListener,
};

fn inicializar(receptor: TcpListener) {
    let mut peticion: Vec<&str> = Vec::new();
    let mut respuesta = String::new();
    let mut lector_buffer;

    for recibido in receptor.incoming() {
        let recibido = recibido.expect("Unable to accept");
        lector_buffer = BufReader::new(recibido);
        lector_buffer
            .read_line(&mut respuesta)
            .expect("could not read");
        peticion = respuesta.split_whitespace().collect();

        println!("quote es {}", peticion[0]);
    }
}

Выдает эту ошибку:

error[E0502]: cannot borrow `respuesta` as mutable because it is also borrowed as immutable
  --> src/lib.rs:12:24
   |
12 |             .read_line(&mut respuesta)
   |                        ^^^^^^^^^^^^^^ mutable borrow occurs here
13 |             .expect("could not read");
14 |         peticion = respuesta.split_whitespace().collect();
   |         --------   --------- immutable borrow occurs here
   |         |
   |         immutable borrow might be used here, when `peticion` is dropped and runs the `Drop` code for type `std::vec::Vec`

Как мне заставить это работать?

1 Ответ

2 голосов
/ 29 октября 2019

В цикле вы заполняете буфер, который вы разделяете между соединениями. И при каждом соединении вы разделяете его снова.

Вы хотите разделить только для текущего соединения:

fn inicializar(receptor: TcpListener) {
    for recibido in receptor.incoming() {
        let recibido = recibido.expect("Unable to accept");
        let mut lector_buffer = BufReader::new(recibido);
        let mut respuesta = String::new();
        lector_buffer
            .read_line(&mut respuesta)
            .expect("could not read");
        let peticion: Vec<&str> = respuesta.split_whitespace().collect();
        println!("quote es {}", peticion[0]);
    }
}

Если вы хотите сохранить строку вне цикла, вы, вероятно, захотитеиспользовать экземпляры String, а не просто &str (потому что они являются указателями и должны указывать на что-то, что сохраняется).

Это может быть что-то вроде

fn inicializar(receptor: TcpListener) {
    let mut peticions: Vec<Vec<String>> = Vec::new();
    for recibido in receptor.incoming() {
        let recibido = recibido.expect("Unable to accept");
        let mut lector_buffer = BufReader::new(recibido);
        let mut respuesta = String::new();
        lector_buffer
            .read_line(&mut respuesta)
            .expect("could not read");
        let peticion: Vec<String> = respuesta
            .split_whitespace()
            .map(|s| s.to_string())
            .collect();
        println!("quote es {}", peticion[0]);
        peticions.push(peticion);
    }
    // you can use peticions here, or even return it
}

На данный момент вам нужно структурировать вашу программу, определив структуры, чтобы избежать работы с Vec s из Vec s.

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