std::io::ErrorKind
は、変異体__Nonexhaustive
を有する。 この亜種が存在しない場合、何が問題なのか分かりません。ErrorKindの目的は何ですか?
この亜種の目的は何ですか?
std::io::ErrorKind
は、変異体__Nonexhaustive
を有する。 この亜種が存在しない場合、何が問題なのか分かりません。ErrorKindの目的は何ですか?
この亜種の目的は何ですか?
match
ステートメントを安定コード内に強制的にキャッチオール_
の腕を持つように設定することで、将来的に列挙型を拡張できるように設計されています。
バリアントを付加し、具体的には、the variant is marked unstableなどが安定したチャンネルで呼ぶことができず、このコードは、安定な錆で正常にコンパイルした場合ので、コンパイラは
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 => {}
^~~~~~~~~~~~~~~~~~~~~~~~~~
ようなコードを拒否将来のバージョンでに変更すると、上記のような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 => {}
_ => {}
}
}
これは、任意の変異体が、将来的にに(新しいIO機能用など新しいエラーの可能性)を追加したことを意味は、_
腕の下に落ち、安定したコードウォンを既存ます壊れない
この隠された変種の目的は、(理由__Nonexhaustive
の存在を正確にコンパイルされません)このような何かを書くことからあなたを防ぐためのものです:
use std::io::ErrorKind;
fn main() {
let error_kind: ErrorKind = unimplemented!();
match error_kind {
ErrorKind::NotFound => unimplemented!(),
ErrorKind::PermissionDenied => unimplemented!(),
ErrorKind::ConnectionRefused => unimplemented!(),
ErrorKind::ConnectionReset => unimplemented!(),
ErrorKind::ConnectionAborted => unimplemented!(),
ErrorKind::NotConnected => unimplemented!(),
ErrorKind::AddrInUse => unimplemented!(),
ErrorKind::AddrNotAvailable => unimplemented!(),
ErrorKind::BrokenPipe => unimplemented!(),
ErrorKind::AlreadyExists => unimplemented!(),
ErrorKind::WouldBlock => unimplemented!(),
ErrorKind::InvalidInput => unimplemented!(),
ErrorKind::InvalidData => unimplemented!(),
ErrorKind::TimedOut => unimplemented!(),
ErrorKind::WriteZero => unimplemented!(),
ErrorKind::Interrupted => unimplemented!(),
ErrorKind::Other => unimplemented!(),
ErrorKind::UnexpectedEOF => unimplemented!(),
ErrorKind::UnexpectedEof => unimplemented!(),
// note: no wildcard match arm here
};
}
のなぜ開発の理由標準ライブラリではこれをやりたくないのですが、将来はにバリアントを追加する機能を保持することです。 __Nonexhaustive
バリアントを使用すると、個々のバリアントを処理するだけで網羅的な一致を防ぐことができます。あなたには完全な一致を持つワイルドカードが必要です。
Rustでは、match
式は、一致する式のすべての可能なパターンに対応する腕があることを要求するため、match
式は常に明確で明示的な値を持ちます。すべてのパターンをカバーするmatch
は、という完全なと一致します。 enum
の場合、Rustはすべてのバリアントを単純にリストすることができます。たとえば、のみNone
とSome
という名前の2つの変種を、持っているOption
、と、私たちは書くことができます:それはoption
のためのすべての可能なパターンをカバーしているため
fn main() {
let option: Option<()> = unimplemented!();
match option {
None => unimplemented!(),
Some(()) => unimplemented!(),
};
}
これmatch
は、罰金コンパイルします。しかし、Option
タイプが別のバリアントを取得した場合、コードはもはや網羅的ではないので、もはやコンパイルされません。もちろん、これはOption
では意味をなさないので、Option
タイプは "非網羅的"ゲームを再生しません。しかし、__Nonexhaustive
が存在しない場合は、にバリアントを追加することは大きな変更になります。で完全一致(ワイルドカードなし)したコードは突然コンパイルを停止します。このコードはあなたのアプリケーションが依存している箱に入っている可能性があります。その破損によりのクレートが修正されるまでRustをアップグレードできなくなる可能性があります。