// dictionary
Option型.
Option<T>は、値が「ある」か「ない」かを表す標準ライブラリの列挙型です1。値が存在することを表すSome(値)と、存在しないことを表すNoneという2つのバリアントを持ちます。多くの言語ではnullやnilで値の不在を表現しますが、Rustにはnull参照がなく、値が欠けうる場面では必ずOption<T>を使うことで、「値がないかもしれない」という事実を型として明示します。
fn find_price(item: &str) -> Option<i32> {
match item {
"りんご" => Some(120),
"みかん" => Some(80),
_ => None, // 該当する商品なし
}
}
fn main() {
let price = find_price("りんご");
match price {
Some(value) => println!("価格: {value}円"),
None => println!("商品が見つかりません"),
}
}Playgroundで開くnull安全性
null参照の考案者であるTony Hoareは、これを自ら「10億ドルの過ち」と呼んでいます2。値がnullかもしれないという可能性を型システムで扱わない言語では、nullチェックの漏れをコンパイラが検出できず、実行時のnull参照エラーとして表面化します。Rustは参照にnullを許さず、値が欠ける可能性をOption<T>という型で表現するため、チェック漏れは網羅性チェックによってコンパイル時に検出されます。
Option<T>とTは別の型
Option<T>とTは異なる型として扱われるため、Option<i32>の値をそのままi32として計算に使うことはできません。
fn main() {
let stock: Option<i32> = Some(3);
let total = stock + 1; // エラー: E0369(Option<i32>に対する`+`演算子は未実装)
}Playgroundで開く値を使うには、match式やunwrap系のメソッドで中身を取り出す必要があります。取り出しを忘れたままTとして扱おうとするコードは、この型の違いによってコンパイルが通らなくなります。
補足
core/stdどちらに定義されているか
Option<T>はcore::optionで定義されており、OSにも依存しない標準ライブラリの最下層であるcoreクレートの一部です。stdはこれを再エクスポートしており、さらにプレリュードに含まれるため、useなしでOption・Some・Noneをそのまま書けます1。
Footnotes
-
std::option::Option —
pub enum Option<T> { None, Some(T) }として定義されています。 ↩ ↩2 -
Tony Hoare, “Null References: The Billion Dollar Mistake”(2009年の講演) ↩
この辞書が使われているページ
backlinks 13