Reputation: 31
Using the following code:
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]);
}
}
Yields this error:
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`
How can I make it work?
Upvotes: 1
Views: 687
Reputation: 382434
In the loop you're filling a buffer, which you share between connections. And at each connection you're splitting it again.
You want to split only for the current connection:
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]);
}
}
If you want to keep the string outside the loop, you probably want to use instances of String
rather than just &str
(because they're pointers and they have to point to something which is kept).
This can be something like
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
}
At this point you need to structure your program by defining structs to avoid dealing with Vec
s of Vec
s.
Upvotes: 2