Edit Page

制御フロー(ツアー)

他のプログラム言語と同様に、Kotlinもコード片を評価した結果がtrueかどうかによって処理を決定する事が出来ます。 そのようなコード片を条件式(conditional expressions)と呼んだりします。 また、Kotlinはループを作成し、処理を繰り返す事も出来ます。

条件式

Kotlinには条件式をチェックする目的で、ifwhenがあります。

もしifwhenのどちらにしようか迷ったら、whenを使う事をオススメします。そちらの方がより安全で頑強なプログラムとなるからです。

If

ifの使い方は、その後にカッコ()の中に条件式を入れて、その次にその結果がtrueだったら実行したいアクションを中括弧{}の中に入れます:

fun main() { //sampleStart val d: Int val check = true if (check) { d = 1 } else { d = 2 } println(d) // 1 //sampleEnd }

Kotlinには三項演算子、condition ? then : elseがありません(訳注:C言語などの言語にはあるがKotlinには無い機能)

三項演算子の代わりに、Kotlinはifを式として使う事が出来ます。 ifを式として使う時は、中括弧{}がありません:(訳注:中括弧なしでも構わない、という意味だと思う)

fun main() { //sampleStart val a = 1 val b = 2 println(if (a > b) a else b) // 結果の値: 2 //sampleEnd }

When

条件式に対して複数の分岐がある場合はwhenを使います。 whenは文としても式としても使う事が出来ます。

whenを文として使う時の例は以下のようになります:

  • 条件文をカッコ()の中に入れ、実行すべきアクションを中括弧{}の中に入れます
  • 各分岐では、->を使って条件とアクションを分けます
fun main() { //sampleStart val obj = "Hello" when (obj) { // obj が "1" と等しいかをチェック "1" -> println("One") // obj が "Hello" と等しいかをチェック "Hello" -> println("Greeting") // デフォルトの文 else -> println("Unknown") } // Greeting //sampleEnd }

分岐の条件は一つずつ順番にチェックされて、最初に条件を満たすまでチェックが続く事に注目してください。 言い換えると最初に条件に一致した分岐だけが実行されます。

以下はwhenを式として使う例です。whenシンタックスがそのまま変数に直接代入されています:

fun main() { //sampleStart 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 //sampleEnd }

whenを式として使う場合は、コンパイラが分岐の条件節ですべての可能性が尽くされていると判定出来る場合を除いては、else節が必須となります。

さきほどの例ではwhenは変数とマッチングするのに便利である事が見て取れました。 ですがwhenはさらに、連鎖するBoolean式をチェックするのにも有用です:

fun main() { //sampleStart val temp = 18 val description = when { // もし temp < 0 が trueなら、descriptionに "very cold" をセット temp < 0 -> "very cold" // もし temp < 10 が trueなら、descriptionに "a bit cold" をセット temp < 10 -> "a bit cold" // もし temp < 20 が trueなら、 descriptionに "warm" をセット temp < 20 -> "warm" // もしここまでの条件が一つも成立してなければ、description を "hot" にセット else -> "hot" } println(description) // warm //sampleEnd }

範囲(Range)

ループについての話をする前に、ループでどの範囲を反復処理をするかを指定するのに使えるrangeというものを、どのように構築するかを知っておくと良いでしょう。

Kotlinでもっとも一般的なrangeの作り方は、..演算子 を使う方法です。例えば、1..41, 2, 3, 4 という意味になります。

終わりの値を含まないrangeを作りたい場合は、..<演算子 を使います。例えば、1..<41, 2, 3 という意味になります。

逆の順序でrangeを作りたい場合はdownToを使います。例えば、4 downTo 14, 3, 2, 1 という意味になります。

1以外のステップで増えていくようなrangeを作りたい場合は、stepを使ってお望みの増加幅を指定します。 例えば、1..5 step 21, 3, 5 という意味になります。

ここまで話した事は Char のrangeでも同様となります:

  • 'a'..'d''a', 'b', 'c', 'd' という意味になります
  • 'z' downTo 's' step 2'z', 'x', 'v', 't' という意味になります

ループ

プログラムにおいて最も一般的なループ構造といえば、forwhileでしょう。 forはrangeの値に渡って繰り返し処理を行いたい時に使います。 whileは特定の条件が満たされるまで処理をし続けます。

For

rangeについて新たに学んだ知識をもとに、数字を1から5まで繰り返してその数字をprintするforループを作る事が出来ます。

カッコ () の中にイテレータかrangeを、キーワードの in とともに置きます。 そして行いたいアクションを中括弧 {} の中に置きます:

fun main() { //sampleStart for (number in 1..5) { // number が iterator で 1..5 が range print(number) } // 12345 //sampleEnd }

(訳注:iteratorでは無いような…)

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

fun main() { //sampleStart val cakes = listOf("carrot", "cheese", "chocolate") for (cake in cakes) { println("美味しい! $cake ケーキだ!") } //美味しい! carrot ケーキだ! //美味しい! cheese ケーキだ! //美味しい! chocolate ケーキだ! //sampleEnd }

While

while は2通りの使い方があります:

  • 条件式がtrueの間はコードブロックを実行し続ける (while)
  • コードブロックをまず実行し、そしてその後に条件式をチェックする (do-while)

最初のユースケースでは (while):

  • whileループを続ける条件となる条件式を、カッコ () の中に宣言する
  • 実行したいアクションを、中括弧 {} の中に置く

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

fun main() { //sampleStart var cakesEaten = 0 while (cakesEaten < 3) { println("ケーキを食べろ") cakesEaten++ } // ケーキを食べろ // ケーキを食べろ // ケーキを食べろ //sampleEnd }

二番目のユースケースでは (do-while):

  • whileループを続ける条件となる条件式を、カッコ () の中に宣言する
  • 実行したいアクションを、中括弧 {} の中に、doキーワードとともに定義する
fun main() { //sampleStart var cakesEaten = 0 var cakesBaked = 0 while (cakesEaten < 3) { println("ケーキを食べろ") cakesEaten++ } do { println("ケーキを焼け") cakesBaked++ } while (cakesBaked < cakesEaten) // ケーキを食べろ // ケーキを食べろ // ケーキを食べろ // ケーキを焼け // ケーキを焼け // ケーキを焼け //sampleEnd }

条件式とループについてさらに知りたい人は、条件式とループを参照ください。

今やあなたはKotlinの制御フローの基礎を理解しました。あなた自身の関数を書く方法を学ぶ時が来ました。

練習問題

練習問題 1

when式を使って、ゲームボーイのボタンの名前を入れたらそのボタンで実行される事をprintするように以下のプログラムを変更せよ。

Button アクション
A Yes
B No
X Menu
Y Nothing
それ以外 そんなボタンありません
fun main() { val button = "A" println( // ここにコードを書いてね ) }
解答例
fun main() {
    val button = "A"
    
    println(
        when (button) {
            "A" -> "Yes"
            "B" -> "No"
            "X" -> "Menu"
            "Y" -> "Nothing"
            else -> "そんなボタンありません"
        }
    )
}

練習問題 2

スライスされたピザを数えて行って、8スライスでまるまるピザ一枚になるまで数える以下のプログラムがあります。 このプログラムを二つの方法でリファクタリングしてください:

  • while ループを使って
  • do-while ループを使って
fun main() { var pizzaSlices = 0 // Start refactoring here pizzaSlices++ println("ピザが $pizzaSlices 片しか無い :(") pizzaSlices++ println("ピザが $pizzaSlices 片しか無い :(") pizzaSlices++ println("ピザが $pizzaSlices 片しか無い :(") pizzaSlices++ println("ピザが $pizzaSlices 片しか無い :(") pizzaSlices++ println("ピザが $pizzaSlices 片しか無い :(") pizzaSlices++ println("ピザが $pizzaSlices 片しか無い :(") pizzaSlices++ println("ピザが $pizzaSlices 片しか無い :(") pizzaSlices++ // End refactoring here println("ピザが $pizzaSlices 片! やったね! ピザがまるごと一枚あるよ! :D") }
解答例 1
fun main() {
    var pizzaSlices = 0
    while ( pizzaSlices < 7 ) {
        pizzaSlices++
        println("ピザが $pizzaSlices 片しか無い :(")
    }
    pizzaSlices++
    println("ピザが $pizzaSlices 片! やったね! ピザがまるごと一枚あるよ! :D")
}
解答例 2
fun main() {
    var pizzaSlices = 0
    pizzaSlices++
    do {
        println("ピザが $pizzaSlices 片しか無い :(")
        pizzaSlices++
    } while ( pizzaSlices < 8 )
    println("ピザが $pizzaSlices 片! やったね! ピザがまるごと一枚あるよ! :D")
}

練習問題 3

Fizz Buzzゲームをシミュレートするプログラムを書け。 あなたの任務は数字を1から100まで増やして行って、3で割れる時はその数字を”fizz”に置き換え、 5で割れる数字は”buzz”で置き換え、3と5の両方で割れる数字は”fizzbuzz”に置き換えたものをprintlnするというものです。

ヒント

数字をカウントするにはforループを使い、各ステップで何を出力するかを決める所ではwhen式を使えば良い。

fun main() { // ここにコードを書いてね }
解答例
fun main() {
    for (number in 1..100) {
        println(
            when {
                number % 15 == 0 -> "fizzbuzz"
                number % 3 == 0 -> "fizz"
                number % 5 == 0 -> "buzz"
                else -> number.toString()
            }
        )
    }
}

練習問題 4

単語のリストがあります。forifを使って、文字lから始まる単語だけをprintしてください。

ヒント

String型の.startsWith()関数を使おう。

fun main() { val words = listOf("dinosaur", "limousine", "magazine", "language") // ここにコードを書いてね }
解答例
fun main() {
    val words = listOf("dinosaur", "limousine", "magazine", "language")
    for (w in words) {
        if (w.startsWith("l"))
            println(w)
    }
}

次回

関数