Kotlin Advent Calendar 2012 (全部俺)

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

4日目:Kotlinで世界に挨拶をしよう

f:id:ngsw_taro:20121203221007j:plain

初日にKotlinの概要を、2日目に機能ウォークスルーを、そして昨日3日目は開発環境についてお話ししました。今日からKotlinの文法や機能について紹介していきます。今日は最も簡単なKotlinプログラム、ということで毎度お馴染みのアレを軸にKotlinコードについて学びます。

Hello, world!

毎度お馴染みのアレと言ったら、そう、HelloWorldプログラムです。簡単で退屈だと思いがちですが、侮るなかれ。画面に何かを表示させるのは楽しいですし、ちょっとした達成感があります。それに簡素なコードであるからこそ見えてくるものがあります。

次のコードを書いて、世界に挨拶をしましょう。

package com.taroid.sample
fun main(args : Array<String>) {
  println("Hello, world!")
}

標準出力に「Hello, world!」と書き出されたら成功です。これであなたはKotlinプログラマ*1!やったね!!ひとしきり感動を噛み締めたら、Kotlinコードの特徴をひとつずつ見ていきましょう。

名前空間レベルに関数を定義できる

1行目にキーワードpackageがあるのがわかりますが、それはJavaと同様に名前空間の宣言を表します。そして次の行でいきなり関数 main の定義が開始されていることに注目してください。Kotlinでは名前空間レベルに関数や変数を定義することができます(もちろんクラスなども)。これは、どのクラスにも属さない関数や変数が許可されることを意味します。たいていの場合、Javaで言う staticメソッドの代わりとして働くでしょう。

ちなみに、Kotlinではpackage宣言さえすれば名前空間が定義されます。Javaのようにファイルシステム依存しません

また、このコードをコンパイルした結果得られるバイトコード上では、なんと関数 main はクラスに属しています。Kotlinでコードを書いているうちは意識する必要はありません。ここらへんの詳しい話は機会があったらします。

関数定義は fun で

関数定義のために用意されているキーワードは fun です。これはおそらく function(関数)の頭の3文字だと思います。これに相当するキーワードが、JavaScriptだとfunctionで、Goだとfuncです。たったの3文字は楽にタイプできますし、楽しい (fun)感じがしますね♪

それから、Kotlinプログラムのエントリポイントとなる関数は上記の関数 main のようなシグネチャをもつ関数です。関数についてはまた今度。

型は変数名の後に

args は変数名です。正確には仮引数名です。args の後にコロンをはさんでArray<String>と記述されていますが、これが args の型です。Javaと異なりKotlinでは変数の型は名前のに書きます。始めのうちは慣れないかも知れませんが、このおかげで型推論がより便利になるんです。詳細は明日(5日目)説明します。

文末にセミコロン不要

3行目には println("Hello, world!") という記述があります。予想通り、この文*2は標準出力にダブルクォートで囲った文字列を書く動作をします。その後にJavaではセミコロンを打っていましたが、Kotlinでは不要です(セミコロンがあってもいい)。

まとめと次回予告

今日はHelloWorldプログラムを通じて、Kotlinコードの特徴をちょっぴり学びました。関数は名前空間レベルに置くことができ必ずしもクラスに属する必要はありません。Javaとは違ってKotlinでは関数定義のためのキーワードが用意されています。変数の型は、その名前の後に記述します。文末にセミコロンは不要です。

明日は変数と型について理解を深めましょう。

日記

寒い...眠い...。寝たい...!

*1:Rubyist, Haskeller, Pythonistaとか様々なカッコイイ呼び方がありますが、Kotlinの場合はなんでしょうね〜。

*2:正確には式。Kotlinではすべての関数呼び出しは値を返すです。この場合、関数 println はUnit型の() という値を返します。

3日目:Kotlinの開発環境

f:id:ngsw_taro:20121201180852j:plain

アドベントカレンダー3日目の今日は、Kotlinの開発環境を紹介します。2つの環境を紹介しますので、好みや用途によって使い分けてください。

お手軽開発環境

 最も手っ取り早く簡単にKotlinを体験したいのならWeb Demoがおすすめです。

f:id:ngsw_taro:20121201223339p:plain

Webブラウザ上でKotlinコードを編集、実行ができます。結構しっかりしていて、構文のハイライトはもちろんのこと、関数名などの補完機能も備えてあります。

また、コンパイラ(やライブラリなど)のバージョンも比較的新しい*1ので、ちょっとKotlinを試したりとか、サンプルコードを書くくらいなら、このWeb Demoで十分です。

使い方

コードをコンパイル・実行するには画面右側にある緑色の再生マークをクリックするだけです。コンパイルあるいは実行結果が画面下に表示されます。

関数名補完機能やリアルタイムなエラー表示を有効にしたい場合は、再生マークのすぐ上にある3つのボタン(On run, Server, Clientと書かれているボタン)のうち真ん中の「Server」と書かれているボタンを選択します。関数名の補完は、レシーバとドットを書いた直後にCtrl-Spaceで関数名の候補が表示されます。

やっぱり統合開発環境

がっつり開発をしたいなら便利なIDEがおすすめです。現時点ではJetBrains社のIntelliJ IDEAが唯一の選択肢です*2。次のURLにアクセスしてIntelliJ IDEA 12をダウンロードしてください。

http://www.jetbrains.com/idea/nextversion/index.html

うまいことインストールしたら、次にKotlinプラグインをインストールします。Preference -> Plugins -> Browse Repositories の順にたどって行くと、インストール可能なプラグイン一覧が表示されますのでKotlinプラグインを選択しインストールします。インストールが完了したらIntelliJ IDEAの再起動を求められるので再起動しましょう。これで準備完了です。

使い方

IntelliJ IDEAで開発を始めるには、まずプロジェクト*3を作成する必要があります。File -> New Project... と選択するとプロジェクト作成のウィザードが開くので通常のJavaプロジェクトを作成するよう質問に答えていきます。新規にJavaプロジェクトを作成した直後の画面は次の図のようになります。

f:id:ngsw_taro:20121202134341p:plain

次にKotlinのソースファイル(ktファイル)をプロジェクトに追加します。プロジェクトルートにあるsrcディレクトリを選択した状態でコンテキストメニューを表示させます。New -> Kotlin File という項目があるはずですので、それを選択します(「Kotlin File」が表示されない場合は、Kotlinプラグインが正しくインストールされていない可能性があります)。すると、ファイル名の入力を促すダイアログが表示されるので、適当な名前を入力します。

ktファイルが作成されると、自動でエディタが開きます。そのとき、エディタ上部に「Kotlin is not configured for module 'ktファイル名'」と通知が表示されます。それに対して、左側の選択肢を選び、JVMをターゲットとしたモジュールを作ることにします(JVM用のライブラリが自動的に追加されます)。

f:id:ngsw_taro:20121202135223p:plain

今度はKotlinのランタイムに必要なライブラリ群を、どこに配置しますか?という旨の質問をされるので、デフォルトの設定で「OK」ボタンを押します。 あとはコードを書いてビルドして実行するだけです。コードは Run -> Run... を選んで実行できます。

動作確認がてら、最初のプログラム

プログラムが実行できるかどうか、次のコードを打って確認してみましょう。

fun main(args : Array<String>) {
  println("Hello, world!")
}

実行すると期待通りに標準出力に「Hello, world!」と書かれているはずです。

まとめと次回予告

今日はKotlinの開発環境を2つ紹介しました。1つがWebブラウザ越しに開発ができるWeb Demo、もう1つがIntelliJ IDEAというIDEです。ちょっと試しにコードを書いてみるなら前者を、アプリケーションの開発をするなら後者を選ぶ、という感じで用途の違いを確認しました。

明日は、今日もちょっぴり登場したHelloWorldプログラムを題材にKotlinコードの基礎を学んでいきたいと思います。

日記

美味しいハンバーグが食べたい...。

*1:いわゆるマイルストーン毎のリリースよりも新しいです。

*2:Eclipse版プラグインも出るらしいです。

*3:Eclipseを使用している方であればお馴染みの用語ですね。

2日目:Kotlin名所見学ツアー

f:id:ngsw_taro:20121129064944j:plain

アドベントカレンダー2日目。今日はKotlin言語を俯瞰して、面白い機能をつまみ食いしていきます。Javaにはない発想がいくつか見られますが、ここではあえて詳細な説明はしません。Kotlinの雰囲気をつかんで、わくわく感を持って明日以降の記事をご覧いただければと思います。

forループ

いきなり退屈そうな話題だとがっかりしないでください。あとで興味深い機能がたくさん登場します。このツアーはまずはここからスタートするというだけです。

for(i in integers) {
    println("count : $i")
}

Kotlinでは、Javaの拡張for文に似ているこの形でしかfor文を使用することができません。ループカウンタをforの括弧内でいじくりまわすということはできないのです。

integers は必ずしも配列である必要はありませんが、ここではInt(整数値)の配列ということにしておきます。

配列

Kotlinでは配列を使用するときに、Javaのように特別な記述はしません。integer の使用の宣言は次のように書けます。

  var integer : Array<Int>

Array という型に、型パラメータとして Int を指定しています。これは通常の文法であり、配列のためだけに用意された文法ではありません。

配列の要素にアクセスするためにはJavaと同様の記法で行います。つまり integers の先頭の要素を参照するには

  integers[0]

と書きます。実はこの記述、Kotlinではやはり配列用の文法ではありません。詳細は後述します。

クラス

KotlinはJavaと同じクラスベースオブジェクト指向言語なのでクラスを定義できます。ここでは配列のためのクラス Array のラッパークラスを作ります。 

class IntArrayWrapper(val length Int{
  private val array = Array<Int>(length) { 0 }
}

関数(あるいはメソッド*1)のようにクラス名の後に続けて引数が宣言されています。ここをプライマリ・コンストラクタ(基本コンストラクタ)と言い、ここに宣言されている変数はそのままそのクラスのプロパティとなります。この例では配列の長さをコンストラクタから受け取るようにしています。

private なプロパティとしてIntの配列を持っています(ここで作りたいのは配列のラッパですので)。

演算子オーバロード

先ほど作ったクラスに関数を追加して、外部へ操作を提供します。つまり関数を定義しましょう。

class IntArrayWrapper(val length : Int) {
  private val array = Array<Int>(length) { 0 }
  
  fun get(index : Int) = array[index]
  
  fun set(index : Int, value : Int) {
    array[index] = value
  }
}

get と set という名前の関数を定義しました。Kotlinの文法に従って記述していますが、なんとなく読めると思います。関数 get では引数に指定したインデックスで、ラップしている配列の要素にアクセスし返しているのがわかります。

 さて、これでIntArrayWrapper のインスタンスについて関数 get や set を呼び出せば配列の各要素にアクセスできるようになりました。

val array = IntArrayWrapper(4) // インスタンス生成
array.set(0, 12345)
println(array.get(0)) // 12345

しかし!なんと!これは次のように記述することもできます。

val array = IntArrayWrapper(4) // インスタンス生成
array[0] = 12345
println(array[0]) // 12345

Kotlinには演算子オーバロードという仕組みが備わっています*2。特定の演算子に対応するシグネチャで定義された関数を持つオブジェクトには、その演算子を用いて演算を行うことが可能です。例えば演算子 + に対応する関数名は plus といった具合です。ここでは get, set という関数が角括弧によるアクセスを可能にしています(これが演算子と言うかは微妙な感じですがw)。

ダックタイピング的イテレータとイテラブル

クラス IntArrayWrapper に要素をセットしたりゲットしたりする機能を追加しました。次にすることはIntArrayWrapper を冒頭で登場したfor文を使用して繰り返す機能の追加です。ご存知の通り、Javaではインタフェース Iterable を実装して Iterator の実装を返して実現しますね。Kotlinではその方法でも可能ですが、インタフェースを実装する必要はないのです。必要な関数さえ定義されていれば、それはもはやイテレータであると見なすのです。Java使いの中には聞き慣れない人もいらっしゃると思いますが、これをダックタイピングと言います。

次のコードが IntArrayWrapper 用のイテレータの定義です。 

class IntArrayWrapperIterator(val array : IntArrayWrapper) {
  
  private var current = 0
  
  fun next() = array[current++]
  
  fun hasNext() = current < array.length
}

拡張関数

イテレータの準備ができたので、IntArrayWrapper をイテラブルにするために関数 iterator を定義します。が、ちょっと待ってください。ちょっと変わった方法で定義します。クラス IntArrayWrapper の外側で定義したいと思います。次のコードはどのクラスにも属さない関数です。

fun IntArrayWrapper.iterator() = IntArrayWrapperIterator(this)

ここで定義した関数 iterator は、IntArrayWrapper のインスタンス関数であるかのように扱うことができます。このようにクラスの外部で定義でき、インスタンス関数のように扱える関数のことを拡張関数と言います。

拡張関数とダックタイピング的イテレータの組み合わせは非常に便利です。例えばKotlinの標準ライブラリではjava.lang.Stringに対してこの手法が使われています。Stringはfinal宣言されているためサブクラスを作れません。そこで拡張関数により関数 iterable が追加されています。そしてダックタイピングによりそのStringはIterableを実装されていると見なされるので、Kotlinではfor文でStringを扱えるのです(String#toCharArray()を使うよりも簡単でしょ?)。

気付いてた?

そろそろ名所見学ツアーはおしまいです。思ったよりも1つ1つの名所を説明しすぎたかな?代わりに回れる名所が少なくなってしまいましたが、Kotlinにはまだまだ魅力的な機能がたくさんあります!

今回登場したコード例で説明を省略したものがいくつかあります。例えばこんな感じ。

  • 文末のセミコロン不要
  • "counter : $i"のように文字列に式の評価値を埋め込めそう
  • 変数の型は変数名の後に(型推論に役立つ)
  • 変数宣言のキーワードが2つ(var と val)
  • 関数定義のキーワードはfun
  • 関数の本体ブロックの代わりに等号をはさんで式がある

気付いてましたか?明日以降はこのへんも紹介していきます!

今日作ったクラスや関数のすべてのコードを次に示します。使用例とエントリポイント(関数 main)も追記しておきますね。

fun main(args : Array<String>) {
  val array = IntArrayWrapper(3)
  array[0] = 5
  array[1] = 2
  
  for(i in array) {
    println(i)
  }
}
 
class IntArrayWrapper(val length : Int) {
  
  private val array = Array<Int>(length) { 0 }
  
  fun get(index : Int) = array[index]
  
  fun set(index : Int, value : Int) {
    array[index] = value
  }
}
 
fun IntArrayWrapper.iterator() = IntArrayWrapperIterator(this)
 
class IntArrayWrapperIterator(val array : IntArrayWrapper) {
  
  private var current = 0
  
  fun next() = array[current++]
  
  fun hasNext() = current < array.length
}

まとめと次回予告

今日はJavaにはないKotlinの特徴的な機能をざっと眺めました。重要な用語をおさらいすると、プライマリ・コンストラクタ、プロパティ、演算子オーバロード、拡張関数、あとおまけでダックタイピングが登場しました。明日はKotlinの開発環境についてお話しします。

日記

この記事書くだけでも3時間以上かかった...。結構ひとりアドベントカレンダーはキツイことがわかりました。6日までにAndroidの方のアドベントカレンダーの記事も書かなくては。

 

*1:このブログでは「関数」と呼ぶことにします。関数とメソッドの呼び分け方については正直コンテキストによって異なりますが、ここでは「関数」です。

*2:ScalaやGroovyにも演算子オーバロードはあります。しかし、Kotlinとの比較はしません。当アドベントカレンダーのサブタイトルの通り、Javaプログラマに対象者を絞っているからです。

1日目:アドベントカレンダーはっじまっるよー!

f:id:ngsw_taro:20121129063626j:plain

 とうとう来た12月!師走!本当に1年って早いですね。今年もだらだらと過ごしてしまいました。来年こそは本気出すっ(キリッ

ってことで今年もアドベントカレンダーの季節がやってきました。クリスマスを楽しく待つためのカレンダー、それがアドベントカレンダーです。それになぞらえて、12月1日から25日(クリスマス)まで日替わりで技術ネタについてブログを書いていく、というのが近年IT系コミュニティで恒例となっています。今年のアドベントカレンダーはAdvent Calendar 2012まとめ - NAVER まとめにまとめられています!

アドベントカレンダーのテーマ

ずばりKotlinです!

Kotlin(コトリン)という新しいプログラミング言語について、クリスマスまで毎日語っていきたいと思います。しかし、ただ語っていくだけではありません。このアドベントカレンダーは2つの特徴があります。

ブログタイトルの通り、全部俺です。というのは通常、アドベントカレンダーは毎日担当者が入れ替わり立ち替わりで記事を書いて進めていくスタイルを取ります。が、当アドベントカレンダーは毎日僕が担当します!

2点目の「Javaプログラマ向けKotlin入門」は、まぁ字面通りの意味なんですが、Javaの経験者をターゲットとしたKotlinの解説をしていきたいと思っています。「プログラミングKotlin(仮)」という解説サイトを公開していますが、より体系的に順を追って丁寧にKotlinを紹介していくよう努めます。具体的には、Javaオンリーのプログラマには馴染みの薄い高階関数などの関数型プログラミング的なアプローチをわかりやすく解説できればと思います。

このアドベントカレンダーを通して、一番お伝えしたいことは

Kotlinかわいい

ということです。あ、つまりKotlinは簡単・強力・便利ということを伝えたいんです!

アドベントカレンダーの読み方

アドベントカレンダーに書く内容と言えばハックした事だったり重箱の隅をつつく内容だったりという傾向があると勝手に思ってますが、当アドベントカレンダーは前述の通りKotlin入門者のための解説ブログです*1

それぞれの記事は独立する内容になるよう努めますが、まれに1つのトピックを前編・後編という感じに分ける場合もあります。興味のある記事を拾い読みすることもできますが、最初から順に読み進めることをおすすめします。

アドベントカレンダーの目次(予定)はこちらです。

Kotlinって何だ?

Kotlinはプログラミング言語のひとつ。IDEで有名なJetBrains社によりApache 2.0ライセンスの下開発されています。Java仮想マシンJVM)上で動作するバイトコードにコンパイルされる、いわゆるJVM言語*2で、産業利用を目的とした本格的なオブジェクト指向言語です。

なぜKotlinなのか?

Javaは今年で17歳です。女の子なら女子高生です。去年にJava 7がリリースされ、来年夏にはJava 8のリリースが予定されています。そんなJavaについて、バージョン間の互換性の問題が話題にのぼることがしばしばあります。またJavaコードの冗長性や、配列の型安全性*3など、いろいろ悩みが多いのが実情だったりします。

 そこで他のJVM言語に目を向けたとき、ScalaやGroovyといった選択肢があると思います。これらは実用的で楽しい言語ですが、JetBrains社は次のように主張しています。

  • Scalaは複雑
  • Groovyは動的で間違いが起きやすい

このような状況を打破するためKotlinプロジェクトがスタートしました。KotlinはJavaよりも簡潔で安全に、Scalaよりもシンプルに、静的型付けによりGroovyよりも安全性とスピートを重視するといったことを目標に設計されています。

これは僕の個人的な意見ですが、上記の特徴に加えてKotlinは、Java経験者にとっての学習コストが小さく、Javaでよく陥りがちなミスを未然に防いでくれるような言語設計なので、業務利用の言語として非常に適していると思います。

まとめと次回予告

アドベントカレンダー初日分はここまでです。今日はKotlinが静的型付けのオブジェクト指向JVM言語であることを学びました。また、その誕生のモチベーションがJavaの抱える問題、Scalaなどの他言語の不満点の補完ということを学びました。明日はKotlinについて特徴的で興味深いいくつかの機能をウォークスルーします。

*1:そのため、既にKotlinに詳しい方には物足りないかも知れません。

*2:KotlinはJavaScriptコードにコンパイルすることも可能です。

*3:「Effective Java 第2版」の項目25「配列よりリストを選ぶ」を参照してください。詳細はジェネリクス(12月16日)で触れる予定です。