Ответ 1
Он разработан, чтобы позволить расширять перечисление ErrorKind
в будущем, заставляя любые операторы match
в стабильном коде иметь захват _
.
В частности, вариант отмечен неустойчивым, поэтому его нельзя ссылаться на стабильный канал, поэтому компилятор отклоняет код, например
fn foo(x: Error) {
match x.kind() {
ErrorKind::NotFound => {}
ErrorKind::PermissionDenied => {}
ErrorKind::ConnectionRefused => {}
ErrorKind::ConnectionReset => {}
ErrorKind::ConnectionAborted => {}
ErrorKind::NotConnected => {}
ErrorKind::AddrInUse => {}
ErrorKind::AddrNotAvailable => {}
ErrorKind::BrokenPipe => {}
ErrorKind::AlreadyExists => {}
ErrorKind::WouldBlock => {}
ErrorKind::InvalidInput => {}
ErrorKind::InvalidData => {}
ErrorKind::TimedOut => {}
ErrorKind::WriteZero => {}
ErrorKind::Interrupted => {}
ErrorKind::Other => {}
ErrorKind::UnexpectedEof => {}
ErrorKind::UnexpectedEOF => {}
ErrorKind::__Nonexhaustive => {}
}
}
<anon>:24:9: 24:35 error: use of unstable library feature 'io_error_internals': better expressed through extensible enums that this enum cannot be exhaustively matched against (see issue #0)
<anon>:24 ErrorKind::__Nonexhaustive => {}
^~~~~~~~~~~~~~~~~~~~~~~~~~
Если этот код успешно скомпилирован на стабильной Rust, то добавление варианта к ErrorKind
в будущей версии приведет к поломке любого кода, который имел match
, как указано выше, а нарушение стабильного кода плохо. Код ломается, потому что совпадения в Rust должны быть исчерпывающими, то есть они должны каким-то образом покрывать каждую возможность, и, таким образом, добавление варианта означает, что возможность не покрывается.
Вместо этого программисты должны написать:
fn foo(x: Error) {
match x.kind() {
ErrorKind::NotFound => {}
ErrorKind::PermissionDenied => {}
ErrorKind::ConnectionRefused => {}
ErrorKind::ConnectionReset => {}
ErrorKind::ConnectionAborted => {}
ErrorKind::NotConnected => {}
ErrorKind::AddrInUse => {}
ErrorKind::AddrNotAvailable => {}
ErrorKind::BrokenPipe => {}
ErrorKind::AlreadyExists => {}
ErrorKind::WouldBlock => {}
ErrorKind::InvalidInput => {}
ErrorKind::InvalidData => {}
ErrorKind::TimedOut => {}
ErrorKind::WriteZero => {}
ErrorKind::Interrupted => {}
ErrorKind::Other => {}
ErrorKind::UnexpectedEof => {}
ErrorKind::UnexpectedEOF => {}
_ => {}
}
}
Это означает, что любые варианты, добавленные в ErrorKind
в будущем (например, новые возможности ошибок для новых функций ввода-вывода), попадут под руку _
, и, следовательно, существующий стабильный код не сломается.