多くのプログラミング言語ではnull値を使用することが可能で、これが実行時にnullポインタの参照エラーを引き起こします。Rustでは、オプションの値を明示的に表現するために、Option<T>という汎用型が導入されており、安全性を提供し、値がない場合を考慮するよう強制します。
値がないこと(例えば、検索結果が見つからなかった場合)は、型に反映されていないと実行時エラーを引き起こすことがよくあります。安全で明示的な空の値の管理は、バグの数を減らします。
Option<T>型は、Some(T)(値が存在する)とNone(値が存在しない)の2つのバリアントを持つenumとして実装されています。これにより、コンパイラはプログラマに両方のケースを考慮させます。オプションの値を明示的に確認せずに使用すると、コンパイルエラーが発生します。
コード例:
fn divide(a: i32, b: i32) -> Option<i32> { if b == 0 { None } else { Some(a / b) } } let res = divide(6, 3); match res { Some(result) => println!("結果: {}", result), None => println!("ゼロで割ることはできません!"), }
主な特徴:
Option<T>はゼロコストの抽象化ですか、それとも各Option変数はより多くのメモリを消費しますか?
はい、大部分の場合、Option<T>はゼロコストであり、型Tが「null」の値を取ることができない場合(例えば、参照型やBox<T>)には特に。Rustは「nullable pointer optimization」最適化を使用しており、追加のメモリは必要ありません。
let value: Option<&u32> = None; // 通常の参照と同じメモリを占有します。
unwrapを安心して使用できますか?
いいえ、unwrap()は値がNoneであるとパニックになります。値があることが保証されている場合にのみ使用するか、unwrap_or、unwrap_or_else、またはパターンマッチングメソッドを選ぶべきです。
Optionはリンク(&T、Option<&T>)とどのように異なりますか?
リンクは常に存在する値を指します。値が存在しない場合は、Option<&T>を使用して「何もないかもしれない」ことを明示的に反映する必要があります。Optionを直接のリンクの代わりに使用することで、ヌルポインタの競合を防ぎます。
関数がOptionを介して検索結果を返すが、呼び出しコードはunwrapを使用して、常に結果があると確信しています。実際には、値がない場合、プログラムは本番環境でクラッシュします。
利点:
欠点:
コードはmatchを使用してOptionを処理し、すべてのケースが明示的に文書化され、テストされています。
利点:
欠点: