Я пытаюсь запрограммировать приложение, которое прослушивает запросы в сокете, а затем добавляет их в очередь для обработки. Часть моего кода выглядит следующим образом:
pub struct Middleware {
listener: TcpListener,
queue: Vec<String>,
servers: Vec<String>,
}
impl Middleware {
pub fn run(&mut self) {
for stream in self.listener.incoming() {
let mut stream = stream.unwrap();
let mut buffer = vec![0u8; 512];
stream.read(&mut buffer).unwrap();
self.queue.push(String::from_utf8(buffer).unwrap());
}
}
}
Тем не менее, если я попытаюсь абстрагировать часть кода в run()
в функцию (буквально просто скопировать/вставить):
impl Middleware {
pub fn run(&mut self) {
for stream in self.listener.incoming() {
let mut stream = stream.unwrap();
self.handle_client(stream);
}
}
fn handle_client(&mut self, mut stream: TcpStream) {
let mut buffer = vec![0u8; 512];
stream.read(&mut buffer).unwrap();
self.queue.push(String::from_utf8(buffer).unwrap());
}
}
Я получаю следующее сообщение об ошибке:
cannot borrow `*self` as mutable because `self.listener` is also borrowed as immutable
--> src/lib.rs:21:13
|
19 | for stream in self.listener.incoming() {
| ------------- immutable borrow occurs here
20 | let mut stream = stream.unwrap();
21 | self.handle_client(stream);
| ^^^^ mutable borrow occurs here
22 | }
| - immutable borrow ends here
Насколько я понимаю, self.listener.incoming()
на самом деле заимствует не только "поле" слушателя, но и всю структуру. И затем, поскольку у нас не может быть изменяемого заимствования одновременно с неизменяемым заимствованием, компилятор жалуется. Тем не менее, я должен сделать self
изменяемым в handle_client()
, иначе я не смогу ничего добавить в его очередь.
Я думал о том, как по-другому структурировать код, чтобы решить эту проблему, но не могу найти решение, не меняя мою структуру Middleware
(например, при удалении некоторых полей и т. д.).
Можно ли как-то структурировать код для использования функции (как в моем втором фрагменте кода)?
handle_client()
заимствуетself.queue
, что не является проблемой, по сравнению с заимствованием толькоself
, что было проблемой в моем коде (потому что это родительский объект заимствованногоself.listener
?)? - person j_beck   schedule 24.10.2017run
видит, что вы заимствуетеself.listener
иself.queue
и что они не пересекаются — вызовhandle_client
не может изменитьself.listener
. - person Shepmaster   schedule 24.10.2017