#rust
#Ржавчина
Вопрос:
fn test() {
use std::path::PathBuf;
use std::fs::File;
let filename: PathBuf = PathBuf::from("hello");
let filename_clone = filename.clone();
match File::open(filename) {
Ok(_fp) => {
unimplemented!();
}
Err(_error) => {
println!("{}", filename_clone.display()); // Works
println!("{}", filename.display()); // Fails
}
}
}
Ошибка:
error[E0382]: borrow of moved value: `filename`
--> src/lib.rs:13:28
|
5 | let filename: PathBuf = PathBuf::from("hello");
| -------- move occurs because `filename` has type `std::path::PathBuf`, which does not implement the `Copy` trait
6 | let filename_clone = filename.clone();
7 | match File::open(filename) {
| -------- value moved here
...
13 | println!("{}", filename.display()); // Fails
| ^^^^^^^^ value borrowed here after move
Мы понимаем, что использование filename
завершается неудачно, потому File::open
что оно заимствовано и еще не выпущено. Тем не менее, в случае open
сбоя (скажем, из-за того, что файл не существует) мы хотим сообщить о фактических входных данных, предоставленных open
. Мы можем обойти это, клонируя имя файла перед его открытием, но в этом случае мы по существу удваиваем объем памяти в ожидании, но не уверенности в возникновении ошибки. Это кажется неправильным.
Каков правильный способ справиться с этим случаем? Как вы выводите информацию из точки сбоя, что обеспечивает выразительную и точную обработку ошибок? Или я что-то недопонимаю в этом механизме, чтобы было понятно?
Комментарии:
1. @JohnKugelman разве это
todo!()
не маскирует ошибку ( play.rust-lang.org /… )?. (Также github.com/rust-lang/rust/issues/69834 ).
Ответ №1:
При вызове File::open(filename)
filename
он не был заимствован, а скорее перемещен, и поэтому вы не сможете использовать его позже.
File::open
принимает любые AsRef<Path>
, и поэтому вы можете передать ссылку на свой PathBuf
(обратите внимание на amp;
):
File::open(amp;filename)
Теперь он был заимствован, и вы можете использовать его позже в коде обработки ошибок.
Комментарии:
1. Теперь это имеет гораздо больше смысла! Спасибо; Комментарий Джона К. заставил меня попытаться понять, почему мой минимальный случай был таким разным, но я вижу, что это была небольшая ошибка. Я признаю, что мне немного неясно, что такое перемещение и заимствование (очевидно), но, надеюсь, я смогу найти хорошее руководство по этому вопросу в Интернете. Опция by-ref — это явно то, что я искал здесь!