【问题标题】:cannot borrow `...` as mutable because it is also borrowed as immutable不能借用 `...` 作为可变的,因为它也被借用为不可变的
【发布时间】:2019-10-29 10:16:51
【问题描述】:

使用以下代码:

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`

我怎样才能让它工作?

【问题讨论】:

    标签: rust


    【解决方案1】:

    在循环中,您正在填充一个缓冲区,您可以在连接之间共享该缓冲区。并且在每个连接处,您都会再次拆分它。

    您只想为当前连接拆分:

    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 的实例,而不仅仅是&amp;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
    }
    

    此时您需要通过定义结构来构建您的程序,以避免处理Vecs 的Vecs。

    【讨论】:

    • OP 可能想要在循环之外声明 respuesta 以在不重新分配的情况下重新使用缓冲区,在这种情况下这样做会很好,但最后需要 respuesta.clear()的循环。见Weird behaviour when using read_line in a loop
    猜你喜欢
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多