Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
Option<T> / Some / None
『Option<T>』は値が存在するか(『Some』)しないか(『None』)を型で表す列挙型です。Rustでは『null』の代わりに『Option』を使うことで、値が存在しない可能性を安全に扱います。
構文
// 値ありの場合はSomeで包みます。
let some_value: Option<i32> = Some(42);
// 値なしの場合はNoneを使います。
let no_value: Option<i32> = None;
// matchで値の有無を分岐します。
match option_value {
Some(x) => println!("値は{}です。", x),
None => println!("値がありません。"),
}
// if letで値があるときだけ処理します。
if let Some(x) = option_value {
println!("値は{}です。", x);
}
構文一覧
| 構文・バリアント | 概要 |
|---|---|
| Some(値) | 値が存在することを表すバリアントです。任意の型の値を1つ保持します。 |
| None | 値が存在しないことを表すバリアントです。型パラメータを持たない空のバリアントです。 |
| match | 『Some(x)』と『None』の2パターンに分岐して処理します。網羅性チェックによりどちらかの漏れがあるとコンパイルエラーになります。 |
| if let Some(x) | 値が『Some』の場合だけ処理するシンタックスシュガーです。『None』のときは何もしません。 |
| while let Some(x) | 値が『Some』の間だけループを継続します。スタックやイテレータの処理に便利です。 |
サンプルコード
fn find_first_even(numbers: &[i32]) -> Option<i32> {
for &n in numbers {
if n % 2 == 0 {
return Some(n); // 偶数が見つかったらSomeで返します。
}
}
None // 見つからなかったらNoneを返します。
}
fn main() {
let nums = vec![1, 3, 5, 4, 7];
// matchで分岐します。
match find_first_even(&nums) {
Some(n) => println!("最初の偶数: {}", n),
None => println!("偶数はありませんでした。"),
}
// if letで値があるときだけ処理します。
if let Some(n) = find_first_even(&nums) {
println!("if let: {}", n);
}
// 空のリストに対して確認します。
let empty: Vec<i32> = vec![];
match find_first_even(&empty) {
Some(n) => println!("偶数: {}", n),
None => println!("リストが空です。"),
}
// while letでスタックを空になるまで処理します。
let mut stack = vec![Some(1), Some(2), None, Some(3)];
while let Some(item) = stack.pop() {
if let Some(n) = item {
println!("スタック: {}", n);
}
}
}
概要
『Option<T>』はRustの標準ライブラリに定義された列挙型で、他の言語の『null』や『nil』に相当する概念を型安全に表現します。『None』の場合に値を取り出そうとするとパニックが発生するため、必ず『match』や『if let』で有無を確認してから使用してください。
関数の戻り値で「見つからないかもしれない」値を返す際に広く使われます。たとえば『HashMap::get()』や『Vec::first()』、文字列の検索系メソッドなど多くの標準ライブラリAPIが『Option』を返します。Rustでは『Option』を使うことでコンパイラが値の存在確認を強制し、NullPointerExceptionのようなランタイムエラーを防ぎます。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。