), компилятор не делает это автоматически. Однако вы можете сделать это вручную, разыменовав существующую изменяемую ссылку, а затем сослаться на нее снова:

у этот код не компилируется:

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()? Может быть, есть еще что-то, чего я не понимаю в проверке заимствований?

Ответы на вопрос(1)

Ваш ответ на вопрос