読者です 読者をやめる 読者になる 読者になる

Kotlin Advent Calendar 2012 (全部俺)

JavaプログラマのためのKotlin入門

7日目:コードは繰り返す

f:id:ngsw_taro:20121206230928j:plain

アドベントカレンダー7日目ー!7日目は安息日にしたいところですが、頑張ります。

今日はループ、繰り返し構文を紹介します。昨日は分岐を学びました。構造化定理によると、あらゆるアルゴリズムは順次、選択(分岐)、反復(繰り返し)の3種類の制御構文の組み合わせで表現できるらしいです。つまり、今日学び終えた頃には、Kotlinで好きなアルゴリズムを実装することができるってことです!理論的には。

whileループ

whileループから説明するJavaやCの入門書って少ない印象を受けますが、どうでしょうか。KotlinにおけるwhileループはJavaのそれと非常に似ています。

var count = 0
while(count < 10) {
  println(count++)
}

Javaのwhileとの違いは、変数のスコープです。do-whileループもKotlinにはありますが、doブロック内で宣言された変数をwhileの条件式から見ることができます(残念ながらコンパイルのバグか、この機能を使うと実行時にクラッシュします)。

do {
  val a = Math.random()
} while(a < 0.5)

これは非常にありがたいです。という理由は2つあります。まず、変数のスコープを最小限にできる、ということです。もう1つの理由は、var ではなく val を使用できるからです。もし、doブロック内の変数のスコープがJavaと同じだとしたら、上記のコードは次のように書く必要があります。

var a : Double
do {
  a = Math.random()
} while(a < 0.5)

forループ

次にforループを紹介します。2日目のエントリで少し触れましたが、KotlinのforループはJavaの拡張for文のような形でしか機能しません。コレクションとその要素を受け取る変数の間にはキーワード in をはさみます。

fun main(args : Array<String>) {
  for(arg in args) {
    println(arg)
  }
}

「コレクション」という言葉を使いましたが、イテレータを提供するオブジェクトならなんでも繰り返せます。具体的には関数 iterator を持つオブジェクトです。関数 iterator は次のようなオブジェクトを返す必要があります。

  • 関数 next を持っている
  • Boolean型を返す関数 hasNext を持っている

もちろん、java.lang.Iterableやjava.lang.Iteratorを実装しても構いませんが、必須ではありません。それから、ここで言う関数はインスタンス関数でも拡張関数でもどっちでもいいのです。実装の話や関数については後日したいと思います。

レンジで繰り返し

Kotlinにはレンジという範囲を表すオブジェクトがあります。具体的にはクラス IntRangeやDoubleRangeによって表現されています。特に整数値のレンジ(IntRange, LongRange)は、forループで繰り返すことができます。

肝心のレンジオブジェクトの生成方法ですが、開始の値と終了の値を演算子 .. で繋ぎます*1

for(i in 1..10) {
  println(i)
}

このコードをコンパイル・実行すると標準出力に1から10までの整数を1つずつ出力していきます。

breakとcontinue

KotlinでもJavaと同じように、ループ内でbreakcontinueができます。ラベル付きbreak, continueもサポートしています。ラベル名は@か@@、または@から始まる名前にする必要があります。

@hoge
for(i in 1..10) {
  for(j in 1..10) {
    if(j == 5) break @hoge
    print(j) // 1, 2, 3, 4と順に表示される
  }
}

まとめと次回予告

今日は繰り返し構文について学びました。whileループはJavaとほとんど同じですが、do-whileでは変数スコープがJavaと異なります。forループはJavaの拡張for文に似ています。イテレータを提供するオブジェクトであれば何でもforで繰り返せます。java.lang.Iterableやjava.lang.Iteratorを実装する必要はありません。レンジという範囲を表すオブジェクトがあることを学びました。

冒頭にも述べましたが、今日までの内容のKotlin文法で、あらゆるアルゴリズムが書けるはずです。明日はちょっとしたアルゴリズムの練習問題をやります。

日記

昨日はJavaScriptとそのユニットテストツールの勉強会に行ってきました。あ、今朝地震ありましたね。

*1:関数 rangeTo と対応しています。演算子オーバロードの詳細については後日。