), компилятор не делает это автоматически. Однако вы можете сделать это вручную, разыменовав существующую изменяемую ссылку, а затем сослаться на нее снова:
у этот код не компилируется:
fn use_cursor(cursor: &mut io::Cursor<&mut Vec<u8>>) {
// do some work
}
fn take_reference(data: &mut Vec<u8>) {
{
let mut buf = io::Cursor::new(data);
use_cursor(&mut buf);
}
data.len();
}
fn produce_data() {
let mut data = Vec::new();
take_reference(&mut data);
data.len();
}
Ошибка в этом случае:
error[E0382]: use of moved value: `*data`
--> src/main.rs:14:5
|
9 | let mut buf = io::Cursor::new(data);
| ---- value moved here
...
14 | data.len();
| ^^^^ value used here after move
|
= note: move occurs because `data` has type `&mut std::vec::Vec<u8>`, which does not implement the `Copy` trait
Подписьio::Cursor::new
таков, что он становится владельцем своего аргумента, в этом случае аргумент является изменяемой ссылкой наVec
.
pub fn new(inner: T) -> Cursor<T>
Это как бы имеет смысл для меня; потому чтоCursor::new
получает право собственности на его аргумент (а не ссылку), мы не можем использовать это значение позже. В то же время это не имеет смысла: мы, по сути, только передаем изменяемую ссылку, и курсор в любом случае выходит из области видимости. вproduce_data
функция, которую мы также передаем изменяемую ссылку наtake_reference
и не выдает ошибку при попытке использоватьdata
опять же, в отличие от внутриtake_reference
.
Я нашел возможным «восстановить» ссылку, используяCursor.into_inner()
, но кажется немного странным делать это вручную, поскольку в обычных случаях использования средство проверки заимствования вполне способно сделать это само.
Есть ли более хорошее решение этой проблемы, чем использование.into_inner()
? Может быть, есть еще что-то, чего я не понимаю в проверке заимствований?