今回からプログラマに優しい現実指向JVM言語 Kotlinを紹介します。最終的なゴールとしてはKotlinを使ったAndroidアプリケーション開発を解説します。今回は導入として、Kotlinの概要や特徴について説明します。
Kotlinとは
Kotlin(コトリン)というプログラミング言語をご存じですか?
IntelliJ IDEAなどのIDE(Integrated Development Environment:統合開発環境)で有名なJetBrains が中心となって開発が進められている新しいプログラミング言語です。2011年夏に発表され、現在Apache 2.0ライセンスのもと、OSS(Open Source Software)として開発環境とそのソースコードが公開されています 。
Kotlinで書かれたコードはJVM(Java Virtual Machine:Java仮想マシン)で動作するJavaバイトコード(おなじみのclassファイル)へコンパイルされます。このようなプログラミング言語をJVM言語 と呼ぶことがあります。ScalaやGroovyもKotlinと同じくJVM言語の1つです。さらにJavaScriptへのコンパイルもサポートしているaltJSの1つでもあります。Androidアプリの開発もサポートしています。
Kotlinは型推論やラムダ式、トレイトなどのモダンな文法、機能を持った静的型付けの本格的なオブジェクト指向言語です。Javaよりも簡潔で安全なコードを書けることが特徴です。執筆時現在のバージョンは0.10.195で、目下開発途中にあります。
なぜKotlinなのか
世の中には、すでに数えきれないほどプログラミング言語が存在します。その中からなぜKotlinを選ぶのか、これについて言及します。
まず言えることは、JVM言語であるということです。Javaは世界中で使われている非常に人気の高い言語です。1995年の登場以来、多くのコードが書かれ、多くのシステムが運用されてきました。Javaは今も進化を続けており、昨年3月にJava SE 8がリリースされたのは記憶に新しいです。しかし、その反面で後方互換性を維持するために記述の冗長さや型安全の問題は改善されにくい現状にあります。そこでJVM言語の登場です。Javaの抱える問題から解放されてプログラミングできるだけではなく、高い信頼と性能を持ったJVM上で動くこと、Javaによって記述された既存のライブラリ/フレームワークなどの資産を活用できるなどのメリットも併せ持っています。
JVM言語だけでもその数は非常に多いです。有名なものでは、ScalaやGroovyが真っ先に思い浮かびますね。このような競合がある中でJetBrainsは、次のようなKotlinの設計ゴールを定めています 。
Java互換
少なくともJavaと同等のコンパイル速度
Javaよりも安全:nullポインタの逆参照[1] のようなありふれた落とし穴のための静的チェックなど
Javaよりも簡潔:型変数の推論、高階関数(クロージャ) 、拡張関数、ミックスインや第一級デリゲーションなどをサポート
Scalaよりもシンプルな方法で、表現力を実用的なレベルに維持する
特徴的なのは、nullポインタの逆参照、すなわちNullPointerException
が起こり得ないようなしくみ(NULL安全 )が言語機能として提供されているところです。その他にもミスを未然に防いでくれる機能があり、Javaよりもつまらないバグを生みにくい言語となっています。安全に重きを置くとコードが複雑になるのではないか、という心配があるかと思いますが、その点もKotlinでは考慮されています。これらのような特徴に加え、Javaから離れすぎない文法による学習コストの小ささから、実際の業務での利用に適しているのではないかと筆者は考えています。
Kotlinの特徴
簡潔、安全、JavaバイトコードとJavaScriptへコンパイル可能、静的型付け、オブジェクト指向、クロージャ……。これらはKotlinを説明する常套句に過ぎません。ですが、どれもKotlinの特徴を端的に表している重要な言葉です。簡単なコードを交えて1つずつ紹介していきます。
簡潔であること
Kotlinはコード自体のシンプルさはもとより、文法すなわち記述ルールも簡潔です。コードが簡潔であることでキーを叩く回数が少なくなり誤りが混入しづらいだけでなく、可読性が増しメンテナンスのコスト低減を期待できます。そして文法が簡潔であることで学習コストが小さく、プログラマのレベルの違いから引き起こされるコードのばらつきを、小さく抑えることができます。リスト1 は毎度おなじみのHelloWorldをKotlinで記述したコードです。
リスト1 KotlinでHelloWorld
package sample
fun main(args: Array<String>) {
val message = "Hello, world!"
println(message)
}
CLIの黒い画面から挨拶文が表示されるだけのプログラムですが、Kotilnの特徴がうかがえます。まずはトップレベルに関数を定義できることがわかります。fun
キーワードが関数定義のために必要なキーワードです。そしてmain
という名前で、Array<String>
型の引数を取る関数がKotlinプログラムのエントリポイントです。変数の型を、変数名の後に置くのもJavaとは異なる点です。
表示するメッセージを変数message
に代入しています。Kotlinではvalキーワードなどを使って変数を宣言します。message
はString
型ですが、それは右辺から推論できるので明示する必要はありません。
println
は引数の値を標準出力に書き出す関数です。;
(セミコロン)を置いて文の終端を明示する必要はありません。同じ行に続けて文を書く場合には;で区切る必要があります。
安全であること
前述のとおり、KotlinはJavaと比べて安全です。型やnull
の扱いが厳格です。たとえばKotlinではキャストやnull
の逆参照による実行時例外が起こることは非常にまれです。
Kotlin ではnull
が代入され得る変数と、され得ない変数を区別します。リスト2 [2] は、b
へnull
を代入しようとしている個所でコンパイルエラーとなります。通常の型(ここではString
)の変数へnull
は代入できないのです。
リスト2 通常の型の変数にはnullを代入できない
val a: String = "Kotlin" // OK
val b: String = null // NG!!
少し変更を加えたリスト3 はコンパイルに成功します。変数とd
の型がString?
になっています。
リスト3 ?付きの型の変数にはnull
を代入できる
val c: String? = "Kotlin" // OK
val d: String? = null // OK
このような?
が末尾に付く型の変数はnull
を代入可能です。しかし、その変数が参照するオブジェクトのメンバへのアクセスに制限が伴います。NullPointerException
を防ぎNULL
安全を貫くためです。NULL
安全については、次回以降で説明します。
JavaバイトコードとJavaScriptへコンパイル可能であること
すでに紹介したようにKotlinはJVM言語であり、コンパイラはJavaバイトコードを出力します。KotlinコードからJavaコードを呼び出せるだけではなく、その逆、つまりJavaコードからKotlinコードを呼び出すこともできます。リスト4 はJavaの標準ライブラリをKotlinコードから呼び出して、テキストファイルの内容を表示する例です。
リスト4 Java標準ライブラリをKotlinから使う
import java.nio.file.Files
import java.nio.file.Paths
fun main(args: Array<String>) {
val path = Paths.get("/memo.txt")
val lines = Files.readAllLines(path)
for (line in lines) {
println(line)
}
}
また、コンパイラはKotlinコードを入力として受け取り、JavaScriptコードを出力できます。ご希望とあればバックエンドとフロントエンド双方でKotlinを使った開発を行えます。
静的型付けであること
Kotlinはコンパイラ言語です。これは単にインタプリタ言語よりも実行速度が速いことを意味するだけではありません。コンパイラは、コンパイル時にソースコードの誤りを発見し、実行可能コードを生成しないので、プログラマはバグを早い段階で発見でき、安全なプログラムを作れます。
オブジェクト指向であること
Kotlinはクラスベースのオブジェクト指向言語です。Javaのように、定義されたクラスからインスタンスを生成できます。リスト5 はクラスを定義し、そのインスタンスを生成するようなシンプルな例です。すでにオブジェクト指向言語を習得されている人は馴染みやすい文法だと感じるでしょう。
リスト5 Userクラスのインスタンスを生成して使う
// Userクラスの定義
class User {
// プロパティ
var id: Long = 0
var name: String = ""
// メソッドのオーバライド
override fun toString(): String {
return "name=" + name
}
}
fun main(args: Array<String>) {
// Userインスタンス生成
// newのようなキーワードは不要
val user = User()
user.id = 12345
user.name = "Taro"
println(user.toString()) // => name=Taro
}
KotlinにはJavaと異なりプリミティブ型はなく、すべてがオブジェクトです。また、プロパティやトレイト、オブジェクト宣言などJavaにはない便利な機能が提供されています。
クロージャの例
Kotlinには第一級オブジェクトとしての関数があります。つまり関数をほかの値と同じように関数の引数として渡したり、戻り値として受け取ったりできます。これにより、より粒度の小さい単位で関数の再利用が可能になり、抽象的なプログラミングが可能になります。これがKotlinの簡潔さを、実現しているしくみの1つです。
Kotlinの標準ライブラリが提供するコレクション操作APIの例をリスト6 に示します。
リスト6 関数を引数として渡してリストを操作する
// 整数のリストを生成
val list = listOf(3, 5, 2, 7, 4)
println(list) // => [3, 5, 2, 7, 4]
// 各要素を2倍にしたリストを生成
val twice = list.map { e -> e * 2 }
println(twice) // => [6, 10, 4, 14, 8]
// 偶数の要素のみにフィルタリングしたリストを生成
val even = list.filter { e -> e % 2 == 0 }
println(even) // => [2, 4]
また、関数はクロージャ(closure・注3 )でもあります。クロージャとは、内部で参照する以外の変数を外部から取り込んでいる関数のことです。コードを交えて説明したほうが理解しやすいと思いますので、クロージャの詳細説明は次回以降に譲ります。
まとめ
今回はKotlinの紹介として、概要と特徴、簡単な文法を取り上げました。KotlinはJetBrains発のオープンソースJVM言語です。その機能や文法は簡潔さと安全性を兼ね備えています。オブジェクト指向、クロージャ、型安全など、モダンな言語にはあってほしい機能はひととおり備えています。とくにNULL安全はユニークな機構です。
次回は開発環境の準備と、プログラミングの例としてFizzBuzzを行います。
第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識
第2特集
「知りたい」「 使いたい」「 発信したい」をかなえる
OSSソースコードリーディングのススメ
特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画]Red Hat Enterprise Linux 9最新ガイド
短期連載
今さら聞けないSSH
[前編]リモートログインとコマンドの実行
短期連載
MySQLで学ぶ文字コード
[最終回]文字コードのハマりどころTips集
短期連載
新生「Ansible」徹底解説
[4]Playbookの実行環境(基礎編)