連載
» 2018年02月01日 05時00分 公開

Android Studioで始めるKotlin入門(2):Javaプログラマーが使うと揶揄されなくなる「Kotlin」の基本構文 (2/3)

[土井毅(著)/山田祥寛(監修),WINGSプロジェクト]

制御文

 制御文については、Javaと似通っていますが、Kotlinらしい機能もあるので、一通り見ておきましょう。

if式

 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" //エラー発生
リスト6 Kotlinのif

 後半に示した、ifを式として使うパターンは注目です。なお、ifを式として使ってその結果を使用する場合はelseが必須です。これは、elseがないと、返す値がなくなってしまうためです。最後のケースのようにelseを省略するとコンパイル時にエラーが発生します。

when

 whenはJavaの「switch〜case」文に似た機能ですが、Kotlinではより強力な機能として生まれ変わっています。

 まずは基本的な数値を比較するパターンから見てみましょう(リスト7)。

val value = 100
when(value){
  100 -> println("100!")
  200 -> println("200!!")
  300 -> println("300!!!")
  else -> println("ELSE")
}
リスト7 基本的なwhenの使用方法
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")
}
リスト8 文字列を対象としたwhenの使用方法
aaa!
処理結果

whenにおける条件の複数指定や範囲指定

 さて、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以下」以外。!を使って条件反転
}
リスト9 whenにおける条件の複数指定や範囲指定
13..20
処理結果

引数なしのwhen

 さらに、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")
}
リスト10 引数なしのwhen
value3 < 20
処理結果(最初に合致しただけ条件だけが処理される)

whenを「式」として使う

 また、Kotlinのwhenはifと同様に「式」としても扱えます(リスト11)。ifの場合と同様、elseを省略するとコンパイル時にエラーが発生します。

val value5 = "Doi"
val value6 = when(value5){ //when式の結果を変数に代入
  "Doi" -> "土井"
  "Yamada" -> "山田"
  else -> "それ以外の人" //elseがないとコンパイル時にエラー
}
println(value6)
リスト11 whenを「式」として使う
土井
処理結果

 このように、Kotlinのwhenは、一見Javaのswitch文の名前が変わっただけと思いきや、ifの存在価値すら揺るがしかねないほど便利な機能を備えています。ぜひ積極的に使っていきましょう。

for

 リスト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を出力
}
リスト12 forの使用方法

 配列から要素だけではなくインデックスも併せて取得したい場合はリスト13のような書き方も可能です。

val names = arrayOf("Doi", "Yamada", "Sakurai")
 
//配列からインデックスと要素の両方を取得する
for((index, elem) in names.withIndex()){
  println("$index: $elem") //文字列に変数を埋め込んで出力(詳細は次ページで解説)
}
リスト13 インデックスと要素の両方を取得する例
0: Doi
1: Yamada
2: Sakurai
処理結果

 ここでは、配列の「withIndex」メソッドを使い、インデックスと要素の両方を取得してループ内で使用しています。なお、メソッドが複数の値を返していることに驚くかもしれませんが、これはfor文の特別な機能ではなく、Kotlinのメソッド・関数全般で使うことのできる大変便利な機能です。次回以降解説予定ですのでお楽しみに。

whileループ、do〜whileループ

 whileループ、do〜whileループについてはJavaとほぼ同じ構文で扱えるため、解説は省略します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。