Почему стандартная ошибка должна быть помещена в рамку main, а не ошибка io? - PullRequest
2 голосов
/ 08 марта 2020

Возьмем следующий фрагмент кода:

fn main() -> std::result::Result<(), std::io::Error> {
    println!("Bonjour le Monde");
    Ok(())
}

Это прекрасный код, но мне было интересно, что произойдет, если я изменю тип ошибки на std :: error :: Error:

fn main() -> std::result::Result<(), std::error::Error> {
    println!("Bonjour le Monde");
    Ok(())
}

Это больше не хорошо:

ошибка [E0277]: размер для значений типа (dyn std::error::Error + 'static) не может быть известен во время компиляции

Я исправил это так:

fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
    println!("Bonjour le Monde");
    Ok(())
}

Так почему основная функция требует Box <> для стандартных ошибок, а не для ошибок ввода-вывода?

1 Ответ

2 голосов
/ 08 марта 2020

std::error::Error - это черта, включенная в стандартную библиотеку. Как указывает Rust, он не может определить, сколько памяти потребуется для хранения Error во время компиляции, поскольку потенциально может использоваться структура любого размера. Таким образом, вам нужно использовать некоторую форму косвенного обращения, например, ссылку, указатель или, в этом случае, Box. См. TRPL Ch.17 для получения дополнительной информации об использовании объектов-черт.

Напротив, std::io::Error - это структура из модуля std::io (которая также реализует std::error::Error) , Rust знает , насколько велика эта структура, поэтому она может создать мономорфизацию Result, которая ее использует.

...