Kotlin、when 式の基本構文の解説とパターン
Java を理解している方は、概要的には、「switch case」の「Kotlin」版と言えば理解しやすでしょう。
ただし、同じではありませんので、細かい内容を解説します。
もちろん、Java を知らない方でも問題なく理解できる内容となっていますので全く問題ありません。
また、「if」の代わりに利用もできます。
場合によっては、「if」よりも「when」のう方が可読性が向上する場合も多々ありますので、しっかりと学び、積極的に利用したい構文となっています。
また、式の結果を直接変数へ代入することもできます。
Java との比較
※ こちらの、項目は「Java」を知らない方は読み飛ばして問題ありません。
- Java の 「switch」 は、「数値」「文字列」「列挙型」しか分岐できませんでしたが、Kotlin の 「when」 ではオブジェクトで利用することができます。
- 文法は、java での「switch」 が 「when」になります。また、「case:」が「->」になります。
- java は、「break」 を記述しないと次の「case」文も実行されてしまいますが、Kotlin の 「when」 では実行されず自動的に「when」式を終了し、次の処理へと進みます。
- java で「default」と記述した文法が 「else」となります。
when の基本
「when」の基本構文は大きく2つあります。
引数ありと、なしの場合になります。
引数あり
文法
「引数」で渡した値が「変数1」の場合は「処理1」が実行され、「変数2」の場合は「処理2」、「引数」が全ての「変数」と一致しない場合は「else」が実行されます。
「break」は必要ありません。
処理完了後、「when」式の処理が完了します。
条件は、下記のサンプル以上に複数の条件をいくらでも記述することができます。
「変数1 -> 処理1」「変数2 -> 処理2」「変数3 -> 処理3」「変数4 -> 処理4」・・・・
何もしない場合は、処理を中括弧「{ }」で囲むことで処理内容をなくすことも可能です。
処理は空っぽの意味になります。
when(引数) { 変数1 -> 処理1 変数2 -> 処理2 // 処理が必要ない場合は「{}」 変数2 -> {} // 「else」は省略可能 else -> 処理else }
サンプル
fun getValue(value: Int) { when(value) { 0 -> println("value は 0") 1 -> println("value は 1") 2 -> println("value は 2") 3 -> else -> {} else -> println("value は else") } } // 呼び出しと結果 getValue(0) Log: value は 0 getValue(2) Log: value は 2 getValue(3) Log: value は 3 getValue(10) Log: value は else
引数なし(複数条件を利用することが可能)
文法
when { 条件式1 -> 処理1 条件式2 -> 処理2 else -> 処理else }
サンプル
サンプルでは解説のため、シンプルに条件を1つにしていますが、1つの場合は引数ありの文法を利用するのが好ましいでしょう。
条件には「true」「false」となる条件であれば、どんな書き方でも大丈夫です。
「isBooleanValue」のような変数でも、「isLogin()」のようなメソッドでも問題ありません。
fun getValue(value: Int) { when { value == 0 -> println("value は 0") value == 1 -> println("value は 1") value == 2 -> println("value は 2") else -> println("value は else") } } // 呼び出しと結果 getValue(0) Log: value は 0 getValue(2) Log: value は 2 getValue(10) Log: value は else
サンプル(複数条件)
基本的には、複数条件にて利用します。
fun getValue(value: Int, value2: String) { when { value == 0 && value2 == "テスト" -> println("value は 0、value2 は テスト") value == 1 && value2 == "本番"-> println("value は 1、value2 は 本番") value == 2 -> println("value は 2") else -> println("value は else") } } // 呼び出しと結果 getValue(0, "テスト") Log: value は 0、value2 は テスト getValue(0, "本番") Log: value は else getValue(1, "テスト") Log: value は else getValue(1, "本番") Log: value は 1、value2 は 本番 getValue(2, "テスト") Log: value は 2 getValue(2, "本番") Log: value は 2 getValue(10, "テスト") Log: value は else getValue(10, "本番") Log: value は else
when 応用変、サンプル集
複数の処理を記述したい場合
文法
中括弧「{ }」で囲むことで複数の処理を記述することができます。
when { 条件式1 -> { 処理1-1 処理1-2 } 条件式2 -> { 処理2-1 処理2-2 } else -> { 処理else-1 処理else-2 } }
サンプル
複数行の場合、「{ }」で囲みますが、1行の場合も囲むことが可能です。
もちろん省略可能です。
コードの可読性を考慮して囲む、囲まないを考慮しましょう。
また、「else」の場合も同等です。
fun getValue(value: Int) { when (value) { // 複数行の場合、「{ }」で囲む 0 -> { println("println 複数") println("value は 0") } // 1行の場合でも、「{ }」で明示的に囲むことも可能 1 -> { println("value は 1") } // 1行の場合、「{ }」を省略できる 2 -> println("value は 2") // 「else」の場合も、複数行の場合、「{ }」で囲む // 同じく、1行の場合は、「{ }」を省略できる else -> { println("println 複数") println("value は else") } } } // 呼び出しと結果 getValue(0) Log: println 複数 Log: value は 0 getValue(1) Log: value は 1 getValue(10) Log: println 複数 Log: value は else
in を利用した範囲指定(renge)
文法
引数の箇所に「in x..xx」と数値を記述することで、範囲を指定することができます。
具体的には、3〜10 の範囲の場合は「in 3..10」となります。
when(引数) { 変数1 -> 処理1 変数2 -> 処理2 in x..xx -> 処理renge else -> 処理else }
サンプル
fun getValue(value: Int) { when(value) { 0 -> println("value は 0") 1 -> println("value は 1") 2 -> println("value は 2") // 3〜10 の場合 in 3..10 -> println("value は 3 〜 10") else -> println("value は else") } } // 呼び出しと結果 getValue(0) Log: value は 0 getValue(2) Log: value は 2 getValue(3) Log: value は 3 〜 10 getValue(5) Log: value は 3 〜 10 getValue(10) Log: value は 3 〜 10 getValue(20) Log: value は else
文字列
変数は、文字列でも問題ありません。
ここでは記述しませんが、「Char」型も使えます。
サンプル
fun getValue(value: String) { when(value) { "テスト" -> println("value は テスト") "本番" -> println("value は 本番") else -> println("value は else") } } // 呼び出し getValue("テスト") Log: value は テスト getValue("本番") Log: value は 本番 getValue("テストでない") Log: value は else
列挙型
列挙型を利用することもできます。
「when」式の条件に全ての列挙項目を記述した場合は、「else」は必要ありません。
※ 列挙型の場合、全ての列挙型項目を記述しなかった場合、「else」は必須になります。
サンプル
enum class Number { ONE, TWO, THREE } fun getValue(value: Number) { when(value) { Number.ONE -> println("value は ONE") Number.TWO -> println("value は TWO") // Number.THREE を記述していないので、今回は「else」が必要。 // Number.THREE -> println("value は THREE") // 上記を記述した場合は下記の「else」は不要 else -> println("value は else") } } // 呼び出しと結果 getValue(Number.ONE) Log: value は ONE getValue(Number.TWO) Log: value は TWO getValue(Number.THREE) Log: value は else
is (オブジェクト型)で判定したい場合
オブジェクト型チェックの「is」を利用した条件分岐も可能です。
サンプル
fun getValue(value: Any) { when(value) { is Int -> println("value は Int") is String -> println("value は String") else -> println("value は else") } } // 呼び出しと結果 getValue(0) Log: value は Int getValue("文字列") Log: value は String getValue(true) Log: value は else
引数を利用しない場合、複雑な条件も記述することができます
when 式に引数を利用しない場合は、条件を混在させることもできます。
サンプル
fun getValue(value: Any, value2: Any) { when { value == 0 -> println("value は 0") value2 == "テスト" -> println("value は テスト") value is Int -> println("value は Int") } } // 呼び出しと結果 value は 0 Log: value は 0 value は テスト Log: value は テスト value は Int Log: value は Int
null 判定したい場合
「null」の判定も利用できます。
サンプル
fun getValue(value: Any?) { when (value) { 0 -> println("value は 0") null -> println("value は Int") } } // 呼び出しと結果 getValue(0) Log: value は 0 getValue(null) Log: value は null
直接変数へ代入も可能
「val」「var」変数へ戻り値を代入することも可能です。
サンプル
fun getValue(value: Int) { val message = when(value) { 0 -> "value は 0" 1 -> "value は 1" 2 -> "value は 2" else -> "value は else" } println(message) } // 呼び出しと結果 getValue(0) Log: value は 0 getValue(2) Log: value は 2 getValue(10) Log: value は else
式本体を持つ関数
「Function with an expression body」を利用して、関数へ式を直接返すことも可能です。
サンプル
fun getValue(value: Int) = when (value) { 0 -> println("value は 0") 1 -> println("value は 1") 2 -> println("value は 2") else -> println("value は else") } // 呼び出しと結果 getValue(0) Log: value は 0 getValue(2) Log: value は 2 getValue(10) Log: value は else
まとめ
Kotlin 「when」に関する利用例を紹介しました。
「when」は利用頻度の高い文法なので使いこなせるようになりましょう。