Edit Page

制御フロー

if式

Kotlinでは、ifは式であり、すなわち値を返します。従って、三項演算子は存在しません(条件 ? 真の時 : 偽の時)。なぜなら普通の if がその役割を果たすためです。

// 伝統的な使い方
var max = a 
if (a < b) 
  max = b 
 
// else付き
var max: Int
if (a > b) 
  max = a 
else 
  max = b 
 
// 表現として
val max = if (a > b) a else b

if の分岐はブロックにすることができ、最後の式がそのブロックの値となります:

val max = if (a > b) { 
    print("Choose a") 
    a 
  } 
  else { 
    print("Choose b") 
    b 
  }

もしifを文ではなく式として使用する(例えば値を返したり変数に代入したりする)ならば、その式にはelse分岐が必要です。

ifの文法を参照してください。

when式

when はC言語のような言語におけるswitch演算子の置き換えです。最も簡単な形式では、次のようになります:

when (x) {
  1 -> print("x == 1")
  2 -> print("x == 2")
  else -> { // このブロックに注目してください
    print("x is neither 1 nor 2")
  }
}

when はその引数と条件が満たされる分岐が現れるまで、順番に全ての分岐に対して比較されます。when は式としても文としても使うことができます。 もし式として使用されれば、その値は条件が満たされた分岐が全ての式の値となります。もし文として使用されれば、個別の条件は無視されます。(ifと全く同じく、それぞれの条件はブロックになれるため、その値はブロック内の最後の式のものとなる。)

else条件は他の条件が全て満たされなかった際に評価されます。 もしが式として使用されれば、全てのあり得る場合を分岐条件で網羅できていることをコンパイラが証明できない限りは、else条件は必須です。

もしたくさんの条件を同じ方法で処理する必要がある場合には、分岐条件をコンマでまとめることができます:

when (x) {
  0, 1 -> print("x == 0 or x == 1")
  else -> print("それ以外")
}

分岐条件として任意の式(定数に限らない)を使用することができます:

when (x) {
  parseInt(s) -> print("sはxをエンコードする")
  else -> print("sはxをエンコードしない")
}

inまたは!inを使用すると、コレクションの 範囲 (range) をチェックすることもできます:

when (x) {
  in 1..10 -> print("xは範囲内")
  in validNumbers -> print("xは有効")
  !in 10..20 -> print("xは範囲外")
  else -> print("どれにも該当せず")
}

値をチェックする他の方法として、特定の型のisまたは!isがあります。スマートキャストのおかげで、その型のメソッドやプロパティに追加のチェック無しでアクセスできることに注意してください。

val hasPrefix = when(x) {
  is String -> x.startsWith("prefix")
  else -> false
}

whenif-else if連鎖を代替することもできます。 引数が与えられない場合は、分岐条件は単純なbooleanの式となり、分岐はその条件がtrueの場合に実行されます:

when {
  x.isOdd() -> print("x is odd")
  x.isEven() -> print("x is even")
  else -> print("x is funny")
}

when の文法を参照してください。

Forループ

forループはイテレータによって提供されるものを何でも繰り返し実行します。構文は次のとおりです:

for (item in collection)
  print(item)

本文をブロックにすることもできます。

for (item: Int in ints) {
  // ...
}

前述したように、 for はイテレータとして提供されるものを何でも繰り返し実行します。すなわち:

  • メンバ関数や拡張関数の iterator() は型を返し、
    • メンバ関数や拡張関数の next()
    • メンバ関数や拡張関数の hasNext()Boolean を返します。

これら3つの関数は全て 演算子 (operator) としてマークされる必要があります。

配列のforループはイテレータオブジェクトを作成しないインデックスベースのループにコンパイルされます。

もし配列やリストをインデックス付きで繰り返し処理したいならば、この方法を使用できる:

for (i in array.indices)
  print(array[i])

“範囲の繰り返し実行”は余分なオブジェクトを生成しない最適な実装へコンパイルされることに注意すること。

別方法として、ライブラリ関数の withIndex を使用することもできます:

for ((index, value) in array.withIndex()) {
    println("$indexの要素は$value")
}

forの文法を参照してください。

whileループ

whiledo..while はいつものように動きます:

while (x > 0) {
  x--
}

do {
  val y = retrieveData()
} while (y != null) // y はここで可視(visible)

whileの文法を参照してください。

ループ内でのbreakとcontinue

Kotlinはループ中の従来の breakcontinue 演算子をサポートしています。Returnとジャンプを参照してください。