Skip to content

コントロールフロー

他のプログラミング言語と同様に、Kotlinはコードの一部が真(true)と評価されるかどうかに基づいて決定を下すことができます。このようなコードの一部を条件式 (conditional expressions)と呼びます。また、Kotlinはループを作成して反復処理を行うこともできます。

条件式

Kotlinは条件式をチェックするために ifwhen を提供しています。

ifwhen のどちらかを選ぶ必要がある場合は、以下の理由から when を使用することをお勧めします:

  • コードが読みやすくなる。
  • 分岐の追加が容易になる。
  • コード内のミスが減る。

If

if を使用するには、丸括弧 () 内に条件式を追加し、結果が真の場合に実行するアクションを波括弧 {} 内に追加します:

kotlin
fun main() {
    val d: Int
    val check = true

    if (check) {
        d = 1
    } else {
        d = 2
    }

    println(d)
    // 1
}

Kotlinには三項演算子 condition ? then : else はありません。その代わりに、if を式として使用できます。アクションごとにコードが1行しかない場合、波括弧 {} は省略可能です:

kotlin
fun main() { 
    val a = 1
    val b = 2

    println(if (a > b) a else b) // 値を返す: 2
}

When

複数の分岐を持つ条件式がある場合は when を使用します。

when の使い方:

  • 評価したい値を丸括弧 () 内に置きます。
  • 分岐を波括弧 {} 内に置きます。
  • 各分岐で -> を使用して、チェック内容と、チェックが成功した場合に実行するアクションを分離します。

when は文(statement)としても式(expression)としても使用できます。は何も返しませんが、代わりにアクションを実行します。

以下は when を文として使用する例です:

kotlin
fun main() {
    val obj = "Hello"

    when (obj) {
        // obj が "1" と等しいかチェック
        "1" -> println("One")
        // obj が "Hello" と等しいかチェック
        "Hello" -> println("Greeting")
        // デフォルトの文
        else -> println("Unknown")     
    }
    // Greeting
}

すべての分岐条件は、そのうちの1つが満たされるまで順番にチェックされることに注意してください。したがって、最初に適合した分岐のみが実行されます。

は、後でコード内で使用できる値を返します。

以下は when を式として使用する例です。when 式の結果はすぐに変数に代入され、その後 println() 関数で使用されます:

kotlin
fun main() {
    val obj = "Hello"    
    
    val result = when (obj) {
        // obj が "1" なら、result に "One" をセット
        "1" -> "One"
        // obj が "Hello" なら、result に "Greeting" をセット
        "Hello" -> "Greeting"
        // 以前の条件がどれも満たされない場合、result に "Unknown" をセット
        else -> "Unknown"
    }
    println(result)
    // Greeting
}

これまでに見た when の例には、いずれも obj という対象(subject)がありました。しかし、when は対象なしで使用することもできます。

この例では、対象なしwhen 式を使用して、一連の Boolean 式をチェックしています:

kotlin
fun main() {
    val trafficLightState = "Red" // "Green"、"Yellow"、または "Red" の可能性があります

    val trafficAction = when {
        trafficLightState == "Green" -> "Go"
        trafficLightState == "Yellow" -> "Slow down"
        trafficLightState == "Red" -> "Stop"
        else -> "Malfunction"
    }

    println(trafficAction)
    // Stop
}

しかし、trafficLightState を対象として指定して、同じコードを書くこともできます:

kotlin
fun main() {
    val trafficLightState = "Red" // "Green"、"Yellow"、または "Red" の可能性があります

    val trafficAction = when (trafficLightState) {
        "Green" -> "Go"
        "Yellow" -> "Slow down"
        "Red" -> "Stop"
        else -> "Malfunction"
    }

    println(trafficAction)  
    // Stop
}

対象を指定して when を使用すると、コードの読みやすさとメンテナンス性が向上します。また、when 式で対象を使用すると、Kotlin がすべての考えられるケースがカバーされているか(網羅性)をチェックするのにも役立ちます。対象を使用せずに when 式を書く場合は、else 分岐を提供する必要があります。

条件式の練習

演習 1

2つのサイコロを振って同じ数字が出たら勝ち、という簡単なゲームを作成してください。if を使用して、サイコロが一致した場合は You win :) を、そうでない場合は You lose :( を出力するようにしてください。

TIP

この演習では、ランダムな Int を取得するために Random.nextInt() 関数を使用できるよう、パッケージをインポートしています。パッケージのインポートに関する詳細は、パッケージとインポートを参照してください。

ヒント
サイコロの結果を比較するには、等価演算子 (==) を使用します。
kotlin
import kotlin.random.Random

fun main() {
    val firstResult = Random.nextInt(6)
    val secondResult = Random.nextInt(6)
    // ここにコードを書いてください
}
解答例
kotlin
import kotlin.random.Random

fun main() {
    val firstResult = Random.nextInt(6)
    val secondResult = Random.nextInt(6)
    if (firstResult == secondResult)
        println("You win :)")
    else
        println("You lose :(")
}
演習 2

when 式を使用して、ゲームコンソールのボタン名を入力した際に対応するアクションを出力するように、以下のプログラムを更新してください。

ボタンアクション
AYes
BNo
XMenu
YNothing
その他There is no such button
kotlin
fun main() {
    val button = "A"

    println(
        // ここにコードを書いてください
    )
}
解答例
kotlin
fun main() {
    val button = "A"
    
    println(
        when (button) {
            "A" -> "Yes"
            "B" -> "No"
            "X" -> "Menu"
            "Y" -> "Nothing"
            else -> "There is no such button"
        }
    )
}

For

範囲に関する知識を活かして、1から5までの数字を反復し、毎回その数字を出力する for ループを作成できます。

キーワード in と共に、イテレータと範囲を丸括弧 () 内に配置します。実行したいアクションを波括弧 {} 内に追加します:

kotlin
fun main() {
    for (number in 1..5) { 
        // number がイテレータ、1..5 が範囲です
        print(number)
    }
    // 12345
}

コレクションもループで反復処理できます:

kotlin
fun main() { 
    val cakes = listOf("carrot", "cheese", "chocolate")

    for (cake in cakes) {
        println("Yummy, it's a $cake cake!")
    }
    // Yummy, it's a carrot cake!
    // Yummy, it's a cheese cake!
    // Yummy, it's a chocolate cake!
}

While

while は2つの方法で使用できます:

  • 条件式が真の間、コードブロックを実行する。 (while)
  • 最初にコードブロックを実行し、その後に条件式をチェックする。 (do-while)

最初の使用例 (while):

  • while ループを継続するための条件式を丸括弧 () 内に宣言します。
  • 実行したいアクションを波括弧 {} 内に追加します。

以下の例では、インクリメント演算子 ++ を使用して cakesEaten 変数の値を増やしています。

kotlin
fun main() {
    var cakesEaten = 0
    while (cakesEaten < 3) {
        println("Eat a cake")
        cakesEaten++
    }
    // Eat a cake
    // Eat a cake
    // Eat a cake
}

2番目の使用例 (do-while):

  • while ループを継続するための条件式を丸括弧 () 内に宣言します。
  • 実行したいアクションを、キーワード do を伴う波括弧 {} 内に定義します。
kotlin
fun main() {
    var cakesEaten = 0
    var cakesBaked = 0
    while (cakesEaten < 3) {
        println("Eat a cake")
        cakesEaten++
    }
    do {
        println("Bake a cake")
        cakesBaked++
    } while (cakesBaked < cakesEaten)
    // Eat a cake
    // Eat a cake
    // Eat a cake
    // Bake a cake
    // Bake a cake
    // Bake a cake
}

条件式とループの詳細な情報と例については、条件とループを参照してください。

Kotlin のコントロールフローの基本を学んだので、次は自分自身の関数を書く方法を学びましょう。

ループの練習

演習 1

ピザが8スライス(丸ごと1枚分)になるまでピザのスライスを数えるプログラムがあります。このプログラムを次の2つの方法でリファクタリングしてください:

  • while ループを使用する。
  • do-while ループを使用する。
kotlin
fun main() {
    var pizzaSlices = 0
    // ここからリファクタリングを開始してください
    pizzaSlices++
    println("There's only $pizzaSlices slice/s of pizza :(")
    pizzaSlices++
    println("There's only $pizzaSlices slice/s of pizza :(")
    pizzaSlices++
    println("There's only $pizzaSlices slice/s of pizza :(")
    pizzaSlices++
    println("There's only $pizzaSlices slice/s of pizza :(")
    pizzaSlices++
    println("There's only $pizzaSlices slice/s of pizza :(")
    pizzaSlices++
    println("There's only $pizzaSlices slice/s of pizza :(")
    pizzaSlices++
    println("There's only $pizzaSlices slice/s of pizza :(")
    pizzaSlices++
    // ここでリファクタリングを終了してください
    println("There are $pizzaSlices slices of pizza. Hooray! We have a whole pizza! :D")
}
解答例 1
kotlin
fun main() {
    var pizzaSlices = 0
    while ( pizzaSlices < 7 ) {
        pizzaSlices++
        println("There's only $pizzaSlices slice/s of pizza :(")
    }
    pizzaSlices++
    println("There are $pizzaSlices slices of pizza. Hooray! We have a whole pizza! :D")
}
解答例 2
kotlin
fun main() {
    var pizzaSlices = 0
    pizzaSlices++
    do {
        println("There's only $pizzaSlices slice/s of pizza :(")
        pizzaSlices++
    } while ( pizzaSlices < 8 )
    println("There are $pizzaSlices slices of pizza. Hooray! We have a whole pizza! :D")
}
演習 2

Fizz buzz ゲームをシミュレートするプログラムを書いてください。タスクは、1から100までの数字を順番に出力することですが、3で割り切れる数字は "fizz" に、5で割り切れる数字は "buzz" に置き換えてください。3と5の両方で割り切れる数字は "fizzbuzz" に置き換える必要があります。

ヒント 1
数字を数えるために for ループを使用し、各ステップで何を出力するかを決定するために when 式を使用してください。
ヒント 2
割り算の余りを取得するには剰余演算子 (%) を使用します。余りがゼロかどうかを確認するには 等価演算子 (==) を使用します。
kotlin
fun main() {
    // ここにコードを書いてください
}
解答例
kotlin
fun main() {
    for (number in 1..100) {
        println(
            when {
                number % 15 == 0 -> "fizzbuzz"
                number % 3 == 0 -> "fizz"
                number % 5 == 0 -> "buzz"
                else -> "$number"
            }
        )
    }
}
演習 3

単語のリストがあります。forif を使用して、文字 l で始まる単語のみを出力してください。

ヒント
String 型の .startsWith() 関数を使用してください。
kotlin
fun main() {
    val words = listOf("dinosaur", "limousine", "magazine", "language")
    // ここにコードを書いてください
}
解答例
kotlin
fun main() {
    val words = listOf("dinosaur", "limousine", "magazine", "language")
    for (w in words) {
        if (w.startsWith("l"))
            println(w)
    }
}