#rust #rust-tokio
#Ржавчина #rust-tokio
Вопрос:
Это моя структура (для полноты картины):
struct Client<'a, T>
where
T: AsyncRead AsyncWrite Unpin
{
socket: T,
stage: u8,
n: usize,
buf: amp;'a mut [u8],
}
Затем я реализовал a Future
для структуры, но изменил self
на me
via let me = amp;mut *self;
.
Это компилируется нормально:
impl<'a, T> Future for Client<'a, T>
where
T: AsyncRead AsyncWrite Unpin
{
type Output = io::Result<()>;
fn poll(mut self: Pin<amp;mut Self>, cx: amp;mut Context<'_>) -> Poll<Self::Output> {
let me = amp;mut *self; // <<<<<<<<<< this fixes it, how?!
while me.stage == 1 {
let self_n = me.n;
let mut rb = ReadBuf::new(amp;mut me.buf[..self_n]);
let n = ready!(Pin::new(amp;mut me.socket).poll_read(cx, amp;mut rb));
}
Poll::Pending
}
}
однако, если я удалю это преобразование, это вызовет ошибку проверки заимствования:
impl<'a, T> Future for Client<'a, T>
where
T: AsyncRead AsyncWrite Unpin
{
type Output = io::Result<()>;
fn poll(mut self: Pin<amp;mut Self>, cx: amp;mut Context<'_>) -> Poll<Self::Output> {
// magic line removed
while self.stage == 1 {
let self_n = self.n;
let mut rb = ReadBuf::new(amp;mut self.buf[..self_n]);
let n = ready!(Pin::new(amp;mut self.socket).poll_read(cx, amp;mut rb));
}
Poll::Pending
}
}
error[E0499]: cannot borrow `self` as mutable more than once at a time
--> z.rs:y:x
|
84 | let mut rb = ReadBuf::new(amp;mut self.buf[..RES.len() - self_n]);
| ---- first mutable borrow occurs here
85 | let n = ready!(Pin::new(amp;mut self.socket).poll_read(cx, amp;mut rb));
| ^^^^ ------- first borrow later used here
| |
| second mutable borrow occurs here
Что это такое, из-за let me = amp;mut *self;
чего оно компилируется?
Ответ №1:
Как видно из этого потока, изменяемое заимствование элемента a Pin
требует использования его DerefMut
реализации, которая изменчиво заимствует все Pin
. Таким образом, вы не можете изменчиво заимствовать 2 поля, даже если они не пересекаются. Строка let me = amp;mut *self
(или альтернативно let me = amp;mut self
) использует Pin
DerefMut
реализацию ‘s для генерации a amp;mut Self
из Pin<amp;mut Self>
. Это происходит только один раз, затем через это изменяемое заимствование заимствуются два непересекающихся поля, что не приводит к ошибкам.