制御文については、Javaと似通っていますが、Kotlinらしい機能もあるので、一通り見ておきましょう。
KotlinのifはJavaとほぼ同じように使えますが、Javaのifが「文」であるのに対し、Kotlinのifは「式」である、つまり「値を返せる」という違いがあります。リスト6に幾つかのパターンを示します。
val a = 10 //シンプルなif if(a >= 10) println("Big") //else付きのif if(a >= 10) println("Big") else println("Small") //{}を使ってブロックにする if(a >= 10){ println("Big") }else{ println("Small") } //ifは式なので値を返せる。ここではif式の結果("Big"または"Small")を変数に代入している val ret = if(a >= 10) "Big" else "Small" //ifを式として使う場合、elseは必須 val ret2 = if(a >= 10) "Big" //エラー発生
後半に示した、ifを式として使うパターンは注目です。なお、ifを式として使ってその結果を使用する場合はelseが必須です。これは、elseがないと、返す値がなくなってしまうためです。最後のケースのようにelseを省略するとコンパイル時にエラーが発生します。
whenはJavaの「switch〜case」文に似た機能ですが、Kotlinではより強力な機能として生まれ変わっています。
まずは基本的な数値を比較するパターンから見てみましょう(リスト7)。
val value = 100 when(value){ 100 -> println("100!") 200 -> println("200!!") 300 -> println("300!!!") else -> println("ELSE") }
100!
Javaのswitchとは記法が違いますが、パッと見ただけで処理内容は理解できることでしょう。ケースごとに「case 値: 処理内容」の代わりに「値 -> 処理内容」となっています。ケースの終了を表すbreakはなく、いずれのケースにも該当しなかった場合の処理は、defaultの代わりにelseを使って記述します。
Kotlinでは、文字列を対象とした分岐もリスト8のように書けます。Javaのswitchは長らく文字列を扱えず、Java 7から文字列に対応しました(C#では以前から対応していましたね)。
val str = "aaa" when(str){ "aaa" -> println("aaa!") "bbb" -> println("bbb!!") else -> println("ELSE") }
aaa!
さて、Kotlinのwhenの機能はまだまだこんなものではありません。リスト9は、条件を「,」(カンマ)で複数指定したり、「範囲」(Range)で指定したりする例です。なお、「範囲」については次回以降で扱う予定です。
val value2 = 13 when(value2){ in 1..10 -> println("1..10") //1以上10以下。inと..を使って範囲指定 11, 12 -> println("11 or 12") //11か12。カンマで複数指定 in 13..20 -> println("13..20") //13以上20以下 !in 1..20 -> println("ELSE") //「1以上20以下」以外。!を使って条件反転 }
13..20
さらに、whenは引数を取らないリスト10のような書き方もできます。この場合、whenは並べられた条件式を上から評価し、最初に合致した条件のみを処理します。複数の条件を列挙して処理する場合、Javaなどではif〜elseを連ねて書くため、インデントがどんどん増えて読みづらい記述になってしまいますが、Kotlinのwhenであればすっきりと書けます。ここまで来ると「そもそもifすら要らないのでは?」とまで思えてきますね。
val value3 = 13 val value4 = 5 when{ //引数無しのwhen value3 < 20 -> println("value3 < 20") //任意の条件式を書ける isEven(value3) -> println("Even") //条件には関数なども書ける value4 > 0 -> println("value4 > 0") else -> println("ELSE") }
value3 < 20
また、Kotlinのwhenはifと同様に「式」としても扱えます(リスト11)。ifの場合と同様、elseを省略するとコンパイル時にエラーが発生します。
val value5 = "Doi" val value6 = when(value5){ //when式の結果を変数に代入 "Doi" -> "土井" "Yamada" -> "山田" else -> "それ以外の人" //elseがないとコンパイル時にエラー } println(value6)
土井
このように、Kotlinのwhenは、一見Javaのswitch文の名前が変わっただけと思いきや、ifの存在価値すら揺るがしかねないほど便利な機能を備えています。ぜひ積極的に使っていきましょう。
リスト12のように、KotlinのforはJavaの「拡張for文」と似た書き方になっています。Javaの拡張for文やC#の「foreach文」のように、配列やコレクションから1つずつ要素を取り出して処理します。ただし、JavaにおいてC言語由来のお約束になっていた「for(初期化 ; 条件 ; 増分処理)」という書き方ができなくなっている点には注意が必要です。こういったケースでは「範囲」を使って処理しましょう。
for(i in arrayOf(1,2,3)){ //配列から1つずつ取り出す println(i) //1〜3を出力 } //古くからの書き方はもうできない //for(i=0;i<10;i++) // println(i) //上記と同じ処理 for(i in 0..9){ 範囲から1つずつ取り出す print(i) //0〜9を出力 } //あるいは範囲の別記法を使ったパターン for(i in 0 until 10){ println(i) //0〜9を出力 }
配列から要素だけではなくインデックスも併せて取得したい場合はリスト13のような書き方も可能です。
val names = arrayOf("Doi", "Yamada", "Sakurai") //配列からインデックスと要素の両方を取得する for((index, elem) in names.withIndex()){ println("$index: $elem") //文字列に変数を埋め込んで出力(詳細は次ページで解説) }
0: Doi 1: Yamada 2: Sakurai
ここでは、配列の「withIndex」メソッドを使い、インデックスと要素の両方を取得してループ内で使用しています。なお、メソッドが複数の値を返していることに驚くかもしれませんが、これはfor文の特別な機能ではなく、Kotlinのメソッド・関数全般で使うことのできる大変便利な機能です。次回以降解説予定ですのでお楽しみに。
whileループ、do〜whileループについてはJavaとほぼ同じ構文で扱えるため、解説は省略します。
Copyright © ITmedia, Inc. All Rights Reserved.