Kotlin で条件を記述する

1. 始める前に

プログラミングの基礎として、条件は非常に重要です。条件は、判断を処理するプログラミング言語のコマンドです。条件を使用するとコードが動的になります。つまり、異なる条件を指定することで、異なる動作をさせることができます。

この Codelab では、if/elsewhen のステートメントと式を使用して Kotlin で条件を記述する方法について説明します。

前提条件

  • Kotlin プログラミングの基礎知識(変数を含む)、および println() 関数と main() 関数の知識

学習内容

  • ブール式を記述する方法
  • if/else ステートメントを記述する方法
  • when ステートメントを記述する方法
  • if/else 式を記述する方法
  • when 式を記述する方法
  • カンマを使用して when 条件の複数の分岐について共通する動作を定義する方法
  • in 範囲を使用して when 条件の分岐の範囲について共通する動作を定義する方法
  • is キーワードを使用して when 条件ステートメントを記述する方法

必要なもの

  • Kotlin プレイグラウンドにアクセスできるウェブブラウザ

2. if / else ステートメントを使用して条件を表す

実生活で、直面した状況に応じて行動を変えるということはよくあります。たとえば、寒ければジャケットを着ますが、暖かければ着ません。

寒いときの判断についてのフローチャート。「はい」の矢印は「ジャケットを着る」のメッセージを指し、「いいえ」の矢印は「ジャケットを着ない」のメッセージを指しています。

判断はプログラミングの基本概念でもあります。特定の状況におけるプログラムの動作について記述し、その状況が発生したとき、それに応じてプログラムが動作または反応できるようにします。Kotlin では、ある条件に基づいてプログラムに異なる動作をさせる場合、if/else ステートメントを使用できます。次のセクションでは、if ステートメントを記述します。

ブール式を使用して if 条件を記述する

信号機のところですべきことを運転手に伝えるプログラムを作成するとします。最初の条件である赤信号に注目してください。赤信号のときはどうするでしょうか。「止まれ」です。

赤信号のときの判断についてのフローチャート。「はい」の矢印は「止まれ」のメッセージを指しています。

Kotlin では、この条件を if ステートメントで表現できます。if ステートメントについて詳しく見てみましょう。

if ステートメントを表した図。if キーワードの後に一対の丸かっこが続き、その内部に条件が記述されています。その後に一対の中かっこがあり、本体を囲んでいます。条件ブロックをハイライト表示しています。

if ステートメントを使用するには、if キーワードを使用し、その後に、評価する条件を記述する必要があります。条件はブール式で表す必要があります。式は、値、変数、演算子を組み合わせたものであり、値を返します。ブール式はブール値を返します。

以前、次のような代入演算子について学習しました。

val number = 1

= 代入演算子は、number 変数に 1 値を代入します。

これに対しブール式は、両辺の値または変数を比較する比較演算子で構成されます。比較演算子を見てみましょう。

1 == 1

== 比較演算子は、値を互いに比較します。この式はどのブール値を返すでしょうか。

この式のブール値を確認しましょう。

  1. Kotlin プレイグラウンドを使用してコードを実行します。
  2. 関数本体に println() 関数を追加し、引数として 1 == 1 式を渡します。
fun main() {
    println(1 == 1)
}
  1. プログラムを実行して出力を確認します。
true

1 つ目の 1 値は 2 つ目の 1 値と等しいため、ブール式は true 値(ブール値)を返します。

試してみる

比較演算子 == の他にも、ブール式を作成するために使用できる比較演算子があります。

  • 未満: <
  • 超える: >
  • 以下: <=
  • 以上: >=
  • 等しくない: !=

簡単な式を使用して比較演算子の使い方を練習します。

  1. 引数で、== 比較演算子を < 比較演算子に置き換えます。
fun main() {
    println(1 < 1)
}
  1. プログラムを実行して出力を確認します。

1 つ目の 1 値は 2 つ目の 1 値未満ではないため、出力で false 値が返されます。

false
  1. 他の比較演算子と数字を使用して、最初の 2 つのステップを繰り返しましょう。

簡単な if ステートメントを記述する

ブール式の記述方法の例を確認したところで、最初の if ステートメントを記述してみましょう。if ステートメントの構文は次のとおりです。

if ステートメントを表した図。if キーワードの後に一対の丸かっこが続き、その内部に条件が記述されています。その後に一対の中かっこがあり、本体を囲んでいます。本体ブロックをハイライト表示しています。

if ステートメントは if キーワードで始まり、その後に条件(丸かっこと中かっこで囲まれたブール式)が続きます。本体は、条件の後に続く、一対の中かっこで囲まれた一連のステートメントまたは式です。これらのステートメントまたは式は、条件が満たされた場合にのみ実行されます。つまり、中かっこ内のステートメントは、if 分岐のブール式が true 値を返す場合にのみ実行されます。

赤信号の場合の if ステートメントを記述します。

  1. main() 関数内で trafficLightColor 変数を作成し、"Red" 値を代入します。
fun main() {
    val trafficLightColor = "Red"
}
  1. 赤信号の場合の if ステートメントを追加し、trafficLightColor == "Red" 式を渡します。
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {

    }
}
  1. if ステートメントの本体に println() 関数を追加し、"Stop" 引数を渡します。
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    }
}
  1. プログラムを実行して出力を確認します。
Stop

trafficLightColor == "Red" 式は true 値を返すため、println("Stop") ステートメントが実行され、Stop メッセージが出力されます。

ブール式と条件として trafficLightColor == "Red" の if ステートメントをハイライト表示した図。次の行には、ブール式が true の場合にのみ println("Stop") の本体が実行されるということが記載されています。

else 分岐を追加する

赤信号でないとき運転手に「進め」と伝えるように、プログラムを拡張してみましょう。

赤信号のときの判断についてのフローチャート。「はい」の矢印は「止まれ」のメッセージを指しています。「いいえ」の矢印は「進め」のメッセージを指しています。

else 分岐を追加して if/else ステートメントを作成する必要があります。分岐は、結合することでステートメントまたは式を構成できる、コードの一部分です。else 分岐は if 分岐の後に続く必要があります。

if / else ステートメントを表した図。if キーワードの後に丸かっこが続き、その内部に条件が記述されています。その後に一対の中かっこがあり、本体 1 を囲んでいます。その後に else キーワードと中かっこが続いています。その後に一対の中かっこがあり、本体 2 のブロックを囲んでいます。

if ステートメントの右中かっこの後に、else キーワードを追加し、続けて一対の中かっこを追加します。else ステートメントの中かっこ内に、if 分岐の条件が false の場合にのみ実行される 2 つ目の本体を追加できます。

プログラムに else 分岐を追加します。

  1. if ステートメントの右中かっこの後に、else キーワードを追加し、続けてもう一対の中かっこを追加します。
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {

    }
}
  1. else キーワードの中かっこ内に println() 関数を追加し、"Go" 引数を渡します。
fun main() {
    val trafficLightColor = "Red"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {
        println("Go")
    }
}
  1. プログラムを実行して出力を確認します。
Stop

このプログラムは else 分岐を追加する前と同じように動作しますが、Go メッセージが出力されません。

  1. 青信号のとき運転手に「進め」と伝えるために、trafficLightColor 変数に Green 値を再代入します。
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else {
        println("Go")
    }
}
  1. プログラムを実行して出力を確認します。
Go

こうして、プログラムが Stop メッセージではなく Go メッセージを出力するようになりました。

ブール式として trafficLightColor == "Red" 条件が記載された if / else ステートメントをハイライト表示した図。ブール式が true の場合にのみ println("Stop") の本体が実行されるということが記載されています。else 句内には、ブール式が false の場合にのみ println("Go") ステートメントが実行されるということが記載されています。

trafficLightColor 変数に "Green" 値を再代入したため、if 分岐で評価される trafficLightColor == "Red" 式は、"Green" 値が "Red" 値と等しくないことから、false 値を返します。

その結果、if 分岐内のすべてのステートメントがスキップされ、代わりに else 分岐内のすべてのステートメントが実行されます。つまり、println("Go") 関数は実行されますが、println("Stop") 関数は実行されません。

else if 分岐を追加する

一般的に、信号機には黄色もあり、運転手に「注意して進め」と伝えます。これを反映させるために、プログラムの判断プロセスを拡張してみましょう。

赤信号のときの判断についてのフローチャート。「はい」の矢印は「止まれ」のメッセージを指しています。「いいえ」の矢印は黄信号のときの別の判断を指しています。その判断点からの「はい」の矢印は「注意」のメッセージを指し、「いいえ」の矢印は「進め」のメッセージを指しています。

1 つの if と 1 つの else 分岐を含む if/else ステートメントを使用して、1 つの判断点に対応する条件を記述することを学びました。しかし、判断点が複数ある複雑な分岐は、どのように扱えばよいでしょうか。判断点が複数ある場合、条件を多層にして作成する必要があります。これは、if/else ステートメントに else if 分岐を追加するときに行えます。

if 分岐の右中かっこの後に、else if キーワードを追加する必要があります。else if キーワードのかっこ内に、else if 分岐の条件としてブール式を追加し、その後に一対の中かっこで囲んだ本体を続ける必要があります。この本体は、条件 1 が満たされず、条件 2 が満たされた場合にのみ実行されます。

if / else ステートメントを表した図。if キーワードの後に丸かっこが続き、その内部に条件 1 ブロックが記述されています。その後に一対の中かっこがあり、本体 1 を囲んでいます。その後に else if キーワードと丸かっこが続き、条件 2 ブロックを囲んでいます。その後に一対の中かっこが続き、本体 2 ブロックを囲んでいます。その後に else キーワードともう一対の中かっこが続き、本体 3 ブロックを囲んでいます。

else if 分岐は常に if 分岐の後、else 分岐の前に配置します。1 つのステートメントに複数の else if 分岐を使用できます。

if / else 条件を示す図。if 分岐と else 分岐の間に else if 分岐が複数あります。else if 分岐の部分に、else if 分岐が複数あるというテキストが記載されています。

if ステートメントに、else 分岐なしで if 分岐と else if 分岐を含めることもできます。

if / else ステートメントを表した図。if キーワードの後に丸かっこが続き、その内部に条件 1 ブロックが記述されています。その後に一対の中かっこがあり、本体 1 を囲んでいます。その後に else if キーワードと丸かっこが続き、条件 2 ブロックを囲んでいます。その後に一対の中かっこが続き、本体 2 ブロックを囲んでいます。

プログラムに else if 分岐を追加します。

  1. if ステートメントの右中かっこの後に、else if (trafficLightColor == "Yellow") 式を追加し、続けて中かっこを追加します。
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {

    } else {
        println("Go")
    }
}
  1. else if 分岐の中かっこ内に、println() ステートメントを追加し、"Slow" 文字列引数を渡します。
fun main() {
    val trafficLightColor = "Green"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. trafficLightColor 変数に "Yellow" 文字列値を再代入します。
fun main() {
    val trafficLightColor = "Yellow"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. プログラムを実行して出力を確認します。
Slow

Stop または Go のメッセージではなく、Slow のメッセージが出力されるようになりました。

ブール式 1 として if 句内に trafficLightColor == "Red" 条件が記載され、ブール式 2 として trafficLightColor == "Yellow" 条件が記載された if / else ステートメントをハイライト表示した図。ブール式 1 が true の場合にのみ println("Stop") の本体が実行されるということが記載されています。ブール式 1 が false でブール式 2 が true の場合にのみ println("Slow") の本体が実行されるということが記載されています。ブール式 1 と 2 が false の場合にのみ println("Go") の本体が実行されるということが記載されています。

Slow のメッセージのみが出力され、他の行は出力されない理由は次のとおりです。

  • trafficLightColor 変数に "Yellow" 値が代入されます。
  • "Yellow" 値と "Red" 値は等しくないため、if 分岐のブール式(画像では 1 と表されています)は false 値を返します。if 分岐内のすべてのステートメントがスキップされ、Stop のメッセージは出力されません。
  • if 分岐が false 値を生成するため、プログラムは else if 分岐内のブール式の評価に進みます。
  • "Yellow" 値と "Yellow" 値は等しいため、else if 分岐のブール式(画像では 2 として表されています)は true 値を返します。else if 分岐内のすべてのステートメントが実行され、Slow のメッセージが出力されます。
  • else if 分岐のブール expressiontrue 値を返すため、残りの分岐はスキップされます。そのため、else 分岐内のすべてのステートメントが実行されず、Go のメッセージは出力されません。

試してみる

現在のプログラムにバグが含まれていることにお気付きでしょうか。

ユニット 1 では、コードの構文エラーが原因で Kotlin がコードをコンパイルできず、プログラムを実行できない、コンパイル エラーという種類のバグについて学びました。このプログラムには、プログラムは実行できるものの、想定どおりの出力が得られない、ロジックエラーという別の種類のバグがあります。

たとえば、青信号のときにのみ運転手に運転させるとします。信号機が壊れて消灯している場合はどうでしょうか。運転者に運転させますか?それとも、なんらかの問題が起きていると警告しますか?

あいにく現在のプログラムでは、赤信号または黄信号以外の場合、運転手には「進め」と伝えられます。

この問題を修正します。

  1. trafficLightColor 変数に "Black" 値を再代入して、信号機が消灯している旨を示すようにします。
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else {
        println("Go")
    }
}
  1. プログラムを実行して出力を確認します。
Go

trafficLightColor 変数に "Green" 値が代入されていない場合でも、Go のメッセージが出力されるようになっています。正しい動作が反映されるようにこのプログラムを修正できますか?

赤信号のときの判断についてのフローチャート。「はい」の矢印は「止まれ」のメッセージを指しています。「いいえ」の矢印は黄信号のときの別の判断を指しています。その判断点からの「はい」の矢印は「注意」のメッセージを指し、「いいえ」の矢印は青信号のときの別の判断を指しています。その判断点からの「はい」の矢印は「進め」のメッセージを指し、「いいえ」の矢印は「無効」のメッセージを指しています。

次のとおり出力されるようにプログラムを変更する必要があります。

  • Go のメッセージ: trafficLightColor 変数に "Green" 値が代入された場合のみ
  • Invalid traffic-light color のメッセージ: trafficLightColor 変数に "Red""Yellow""Green" の値が代入されていない場合のみ

else 分岐を修正する

else 分岐はキャッチオール分岐であるため、常に if/else ステートメントの最後に配置されます。これは、その前にある分岐の他の条件がすべて満たされない場合に、自動的に実行されます。そのため else 分岐は、特定の条件を満たしたときにのみアクションを実行する場合には適していません。信号機の場合、else if 分岐を使用して、青信号の条件を指定できます。

else if 分岐を使用して、青信号の条件を評価します。

  1. 現在の else if 分岐の後に、別の else if (trafficLightColor == "Green") 分岐を追加します。
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    }
}
  1. プログラムを実行して出力を確認します。

前にある条件が満たされない場合に実行される else 分岐がないため、出力は空になります。

  1. 最後の else if 分岐の後に、println("Invalid traffic-light color") ステートメントを伴う else 分岐を追加します。
fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}
  1. プログラムを実行して出力を確認します。
Invalid traffic-light color
  1. trafficLightColor 変数に "Red""Yellow""Green" 以外の値を代入して、プログラムを再実行します。

プログラムの出力はどうなりましたか?

青信号の入力の検証として明示的な else if 分岐を用意し、他の無効な入力を捕捉するために else 分岐を用意することをおすすめします。これにより運転手は、青信号の場合にのみ「進め」と指示されるようになります。それ以外の場合、信号機が期待どおりに機能していない旨を伝える明示的なメッセージが出力されます。

3. when ステートメントを複数の分岐に使用する

trafficLightColor プログラムは、複数の条件(分岐)があると複雑に見えます。さらに多くの分岐を持つプログラムを簡素化できるかどうか、疑問に思われるかもしれません。

Kotlin で複数の分岐を扱う場合、if/else ステートメントの代わりに when ステートメントを使用できます。人間の読者(通常はデベロッパー)にとってどれだけ読みやすいかという、可読性が向上します。コードを記述するときは、可読性を考慮することが非常に重要です。たいていの場合、コードの全期間にわたって他のデベロッパーがレビューや変更を行う必要があるからです。可読性に優れていれば、デベロッパーがコードを正しく理解でき、誤ってバグを混入させずに済みます。

考慮する分岐が 3 つ以上ある場合、when ステートメントが優先されます。

when ステートメントの構造を示す図。最初に when キーワード、その後に一対の中かっこがあり、その内部にパラメータ ブロックが記述されています。次に、1 対の中かっこの中で 3 行に場合分けされています。各行の中に条件ブロックがあり、その後に矢印記号と本体ブロックが続いています。場合分けの各行は順番に評価されるということが記載されています。

when ステートメントは、パラメータを通じて 1 つの値を受け取ります。その値が各条件に対して順番に評価されます。最初に満たされた条件に対応する本体が実行されます。各条件と本体は矢印(->)で区切ります。if/else ステートメントと同様に、when ステートメントでは条件と本体の各対を分岐といいます。また、if/else ステートメントと同様に、キャッチオール分岐として機能する else 分岐を when ステートメントの最終条件として追加できます。

if/else ステートメントを when ステートメントで書き換える

信号機プログラムには、すでに複数の分岐があります。

  • 赤信号
  • 黄信号
  • 青信号
  • 他の色の信号

when ステートメントを使用するようにプログラムを変換します。

  1. main() 関数内の if/else ステートメントを削除します。
fun main() {
    val trafficLightColor = "Black"

}
  1. when ステートメントを追加し、引数として trafficLightColor 変数を渡します。
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
    }
}
  1. when ステートメントの本体に、"Red" 条件を追加し、続けて矢印と println("Stop") 本体を追加します。
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
    }
}
  1. その次の行に "Yellow" 条件を追加し、続けて矢印と println("Slow") 本体を追加します。
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
    }
}
  1. その次の行に "Green" 条件を追加し、続けて矢印と println("Go") 本体を追加します。
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
    }
}
  1. その次の行に else キーワードを追加し、続けて矢印と println("Invalid traffic-light color") 本体を追加します。
fun main() {
    val trafficLightColor = "Black"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. trafficLightColor 変数に "Yellow" 値を再代入します。
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}

このプログラムを実行すると、どのような出力が得られるでしょうか。

  1. プログラムを実行して出力を確認します。
Slow

when ステートメントに注釈を付けた図。"Red" -> println("Stop") 行に場合分け 1 の注釈が付けられています。"Yellow" -> println("Slow") 行に場合分け 2 の注釈が付けられています。Green" -> println("Go") 行に場合分け 3 の注釈が付けられています。else -> println("Invalid traffic-light color") 行に場合分け 4 の注釈が付けられています。

次の理由から、出力は Slow のメッセージになります。

  • trafficLightColor 変数に "Yellow" 値が代入されます。
  • 各条件が 1 つずつ順番に評価されます。
  • "Yellow" 値と "Red" 値は等しくないため、最初の本体はスキップされます。
  • "Yellow" 値と "Yellow" 値は等しいため、2 番目の本体が実行され、Slow のメッセージが出力されます。
  • 本体が実行されたため、3 番目と 4 番目の分岐が無視され、when ステートメントが残されます。

複雑な条件を when ステートメントで記述する

ここまでで、trafficLightColor 変数に "Yellow" 値が代入されるときなど、1 つの等しい条件について when 条件を記述する方法を学びました。次は、カンマ(,)、in キーワード、is キーワードを使用して、さらに複雑な when 条件を作成する方法を学びます。

1 から 10 までの数値が素数かどうかを判別するプログラムを作成します。

  1. Kotlin プレイグラウンドを別ウィンドウで開きます。

信号機プログラムには後ほど戻ってきます。

  1. x 変数を定義して、3 値を代入します。
fun main() {
    val x = 3
}
  1. 2357 条件の複数の分岐を含む when ステートメントを追加し、それぞれに続けて println("x is prime number between 1 and 10.") 本体を追加します。
fun main() {
    val x = 3

    when (x) {
        2 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
    }
}
  1. println("x is not prime number between 1 and 10.") 本体を伴う else 分岐を追加します。
fun main() {
    val x = 3

    when (x) {
        2 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. プログラムを実行して、出力が想定どおりであることを確認します。
x is a prime number between 1 and 10.

カンマ(,)を複数の条件に使用する

素数プログラムでは、println() ステートメントが何度も繰り返されています。when ステートメントを記述するとき、カンマ(,)を使用すると、同じ本体に対応する複数の条件を表すことができます。

when ステートメントの構造を示す図。最初に when キーワード、その後に丸かっこがあり、その内部にパラメータ ブロックが記述されています。次に、1 対の中かっこの中で 2 行に場合分けされています。最初の行には、条件 1 ブロックがあり、その後にカンマ、条件 2 ブロック、矢印、本体ブロックが続いています。2 行目には、条件ブロックがあり、その後に矢印記号と本体ブロックが続いています。

上の図では、最初と 2 番目の条件のいずれかが満たされると、対応する本体が実行されます。

この考え方で素数プログラムを書き換えます。

  1. 2 条件の分岐に、357 をカンマ(,)で区切って追加します。
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        3 -> println("x is a prime number between 1 and 10.")
        5 -> println("x is a prime number between 1 and 10.")
        7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. 357 条件の個々の分岐を削除します。
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. プログラムを実行して、出力が想定どおりであることを確認します。
x is a prime number between 1 and 10.

in キーワードを条件の範囲に使用する

複数の条件を示すために、カンマ(,)記号の他に、in キーワードと、when 分岐の値の範囲も使用できます。

when ステートメントの構造を示す図。最初に when キーワード、その後に丸かっこがあり、その内部にパラメータ ブロックが記述されています。次に、1 対の中かっこの中で 2 行に場合分けされています。最初の行には、in キーワードがあり、その後に範囲開始ブロック、2 つのドット、範囲終了ブロック、矢印記号、本体ブロックが続いています。2 行目には、条件ブロックがあり、その後に矢印記号と本体ブロックが続いています。

値の範囲を使用するには、範囲の開始を示す数値を追加し、その後にスペースなしで 2 つのピリオドを追加して、範囲の終了を示す別の数値で閉じます。

パラメータの値が範囲の開始から終了までのいずれかの値と等しいとき、最初の本体が実行されます。

素数プログラムで、数値が 1~10 であり、かつ素数でない場合に、メッセージを出力できますか?

in キーワードを伴う別の分岐を追加します。

  1. when ステートメントの最初の分岐の後に、in キーワードを伴う 2 番目の分岐を追加し、続けて 1..10 範囲と println("x is a number between 1 and 10, but not a prime number.") 本体を追加します。
fun main() {
    val x = 3

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. x 変数を 4 値に変更します。
fun main() {
    val x = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. プログラムを実行して出力を確認します。
x is a number between 1 and 10, but not a prime number.

2 番目の分岐のメッセージは出力されますが、最初または 3 番目の分岐のメッセージは出力されません。

when ステートメントに注釈を付けた図。2,3,5,7 -> println("x is a prime number between 1 and 10.") 行に場合分け 1 の注釈が付けられています。in 1..10 -> println("x is a number between 1 and 10, but not a prime number.") 行に場合分け 2 の注釈が付けられています。else -> println("x isn't a prime number between 1 and 10.") 行に場合分け 3 の注釈が付けられています。

プログラムの流れは次のとおりです。

  • x 変数に 4 値が代入されます。
  • プログラムは最初の分岐の条件の評価に進みます。4 値は 2357 値ではないため、プログラムは最初の分岐における本体の実行をスキップし、2 番目の分岐に進みます。
  • 4 値は 110 であるため、x is a number between 1 and 10, but not a prime number. 本体のメッセージが出力されます。
  • 1 つの本体が実行されるため、プログラムは when ステートメントを離れ、else 分岐を無視します。

is キーワードを使用してデータ型を確認する

is キーワードを条件として使用すると、評価値のデータ型を確認できます。

when ステートメントの構造を示す図。最初に when キーワード、その後に丸かっこがあり、その内部にパラメータ ブロックが記述されています。次に、1 対の中かっこの中で 2 行に場合分けされています。最初の行には、in キーワードがあり、その後にタイプブロック、矢印記号、本体ブロックが続いています。2 行目には、条件ブロックがあり、その後に矢印記号と本体ブロックが続いています。

上の図では、引数の値が指定したデータ型である場合、最初の本体が実行されます。

素数プログラムで、入力が 1~10 の範囲外の整数である場合に、メッセージを出力できますか?

is キーワードを伴う別の分岐を追加します。

  1. xAny 型に変更します。これにより、xInt 型以外の値にすることができます。
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. when ステートメントの 2 番目の分岐の後に、is キーワード、Int データ型、println("x is an integer number, but not between 1 and 10.") 本体を追加します。
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't a prime number between 1 and 10.")
    }
}
  1. else 分岐の本体を println("x isn't an integer number.") 本体に変更します。
fun main() {
    val x: Any = 4

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't an integer number.")
    }
}
  1. x 変数を 20 値に変更します。
fun main() {
    val x: Any = 20

    when (x) {
        2, 3, 5, 7 -> println("x is a prime number between 1 and 10.")
        in 1..10 -> println("x is a number between 1 and 10, but not a prime number.")
        is Int -> println("x is an integer number, but not between 1 and 10.")
        else -> println("x isn't an integer number.")
    }
}
  1. プログラムを実行して出力を確認します。
x is an integer number, but not between 1 and 10.

3 番目の分岐のメッセージは出力されますが、最初、2 番目、4 番目の分岐のメッセージは出力されません。

when ステートメントに注釈を付けた図。2,3,5,7 -> println("x is a prime number between 1 and 10.") 行に場合分け 1 の注釈が付けられています。in 1..10 -> println("x is a number between 1 and 10, but not a prime number.") 行に場合分け 2 の注釈が付けられています。is Int -> println("x is an integer number, but not between 1 and 10.") 行に場合分け 3 の注釈が付けられています。else -> println("x isn't an integer number.") 行に場合分け 4 の注釈が付けられています。

プログラムの流れ:

  • x 変数に 20 値が代入されます。
  • プログラムは最初の分岐の条件の評価に進みます。20 値は 2357 値ではないため、プログラムは最初の分岐における本体の実行をスキップし、2 番目の分岐に進みます。
  • 20 値は 110 ではないため、プログラムは 2 番目の分岐における本体の実行をスキップし、3 番目の分岐に進みます。
  • 20 値は Int 型であるため、x is an integer number, but not between 1 and 10 本体が出力されます。
  • 1 つの本体が実行されるため、プログラムは when ステートメントを離れ、else 分岐を無視します。

試してみる

ここで、信号機プログラムで学んだことを実践しましょう。

一部の国には信号機の色として琥珀色があり、運転者に対し他の国でいう黄信号と同様の警告を行うとします。この追加条件をカバーしつつ元の条件を維持するように、プログラムを変更できますか?

同じ本体を使用して条件を追加する

信号機プログラムに条件を追加します。

  1. まだ開いている場合は、信号機プログラムがある Kotlin プレイグラウンドのインスタンスに戻ります。
  2. 閉じた場合は、Kotlin プレイグラウンドの新しいインスタンスを開いて、次のコードを入力します。
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. when ステートメントの 2 番目の分岐で、"Yellow" 条件の後にカンマを追加し、その後に "Amber" 条件を追加します。
fun main() {
    val trafficLightColor = "Yellow"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. trafficLightColor 変数を "Amber" 値に変更します。
fun main() {
    val trafficLightColor = "Amber"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}
  1. プログラムを実行して出力を確認します。
Slow

4. if / else と when を式として使用する

if/elsewhen をステートメントとして使用する方法を学びました。条件をステートメントとして使用すると、条件に基づいて各分岐がさまざまなアクションを本体で実行できるようになります。

また、条件を式として使用し、条件の分岐ごとに異なる値を返すこともできます。各分岐の本体が似ている場合、条件式を使用すると、条件ステートメントよりもコードの可読性が高くなります。

if / else 式を表した図。val キーワードの後に名前ブロック、等号、if キーワード、条件とそれを囲む丸かっこ、本体 1 とそれを囲む一対の中かっこ、else キーワード、本体ブロックとそれを囲む一対の中かっこが続いています。

式としての条件の構文はステートメントと似ていますが、各分岐の本体の最終行は値または式を返す必要があり、条件は変数に代入されます。

本体に戻り値または式しかない場合は、中かっこを削除してコードを簡潔にできます。

if / else 式を表した図。val キーワードの後に名前ブロック、等号、if キーワード、条件とそれを囲む丸かっこ、式 1 ブロック、else キーワード、式 2 ブロックが続いています。

次のセクションでは、信号機プログラムを通じて if/else 式を見てみましょう。

if ステートメントを式に変換する

この if/else ステートメントでは println() ステートメントが何度も繰り返されています。

fun main() {
    val trafficLightColor = "Black"

    if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}

この if/else ステートメントを if/else 式に変換し、繰り返しを削除します。

  1. Kotlin プレイグラウンドで、前の信号機プログラムに入ります。
  2. message 変数を定義し、if/else ステートメントを代入します。
fun main() {
    val trafficLightColor = "Black"

    val message = if (trafficLightColor == "Red") {
        println("Stop")
    } else if (trafficLightColor == "Yellow") {
        println("Slow")
    } else if (trafficLightColor == "Green") {
        println("Go")
    } else {
        println("Invalid traffic-light color")
    }

}
  1. すべての println() ステートメントと、その中かっこを削除します。ただし、内部の値は残します。
fun main() {
    val trafficLightColor = "Black"

    val message =
      if (trafficLightColor == "Red") "Stop"
      else if (trafficLightColor == "Yellow") "Slow"
      else if (trafficLightColor == "Green") "Go"
      else "Invalid traffic-light color"
}
  1. プログラムの最後に println() ステートメントを追加し、引数として message 変数を渡します。
fun main() {
    val trafficLightColor = "Black"

    val message =
      if (trafficLightColor == "Red") "Stop"
      else if (trafficLightColor == "Yellow") "Slow"
      else if (trafficLightColor == "Green") "Go"
      else "Invalid traffic-light color"

    println(message)
}
  1. プログラムを実行して出力を確認します。
Invalid traffic-light color

試してみる

when ステートメントの代わりに when 式を使用するように信号機プログラムを変換します。

  1. Kotlin プレイグラウンドで、次のコードを入力します。
fun main() {
    val trafficLightColor = "Amber"

    when (trafficLightColor) {
        "Red" -> println("Stop")
        "Yellow", "Amber" -> println("Slow")
        "Green" -> println("Go")
        else -> println("Invalid traffic-light color")
    }
}

println() ステートメントを繰り返さないように when ステートメントを式に変換できますか?

  1. message 変数を作成し、when 式を代入します。
fun main() {
    val trafficLightColor = "Amber"

    val message = when(trafficLightColor) {
        "Red" -> "Stop"
        "Yellow", "Amber" -> "Proceed with caution."
        "Green" -> "Go"
        else -> "Invalid traffic-light color"
    }
}
  1. プログラムの最終行として println() ステートメントを追加し、引数として message 変数を渡します。
fun main() {
    val trafficLightColor = "Amber"

    val message = when(trafficLightColor) {
        "Red" -> "Stop"
        "Yellow", "Amber" -> "Proceed with caution."
        "Green" -> "Go"
        else -> "Invalid traffic-light color"
    }
    println(message)
}

5. おわりに

今回は、条件と、その Kotlin での記述方法について学習しました。

まとめ

  • Kotlin では、if/else 条件または when 条件を使用して分岐を実現できます。
  • if/else 条件における if 分岐の本体は、if 分岐条件内のブール式が true 値を返した場合にのみ実行されます。
  • if/else 条件における後続の else if 分岐は、前の if 分岐または else if 分岐が false 値を返した場合にのみ実行されます。
  • if/else 条件における最後の else 分岐は、前のすべての if 分岐または else if 分岐が false 値を返した場合にのみ実行されます。
  • 分岐が 2 つ以上ある場合は、if/else 条件の代わりに when 条件を使用することをおすすめします。
  • カンマ(,)、in 範囲、is キーワードを使用すると、when 条件に複雑な条件を記述できます。
  • if/else 条件と when 条件は、ステートメントまたは式として機能できます。

詳細