プログラマに優しい現実指向JVM言語 Kotlin入門

第1回Kotlinを勧める理由

今回からプログラマに優しい現実指向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キーワードなどを使って変数を宣言します。messageString型ですが、それは右辺から推論できるので明示する必要はありません。

printlnは引数の値を標準出力に書き出す関数です。;(セミコロン)を置いて文の終端を明示する必要はありません。同じ行に続けて文を書く場合には;で区切る必要があります。

安全であること

前述のとおり、KotlinはJavaと比べて安全です。型やnullの扱いが厳格です。たとえばKotlinではキャストやnullの逆参照による実行時例外が起こることは非常にまれです。

Kotlin ではnullが代入され得る変数と、され得ない変数を区別します。リスト2[2]は、bnullを代入しようとしている個所でコンパイルエラーとなります。通常の型(ここでは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を行います。

Software Design

本誌最新号をチェック!
Software Design 2022年9月号

2022年8月18日発売
B5判/192ページ
定価1,342円
(本体1,220円+税10%)

  • 第1特集
    MySQL アプリ開発者の必修5科目
    不意なトラブルに困らないためのRDB基礎知識
  • 第2特集
    「知りたい」⁠使いたい」⁠発信したい」をかなえる
    OSSソースコードリーディングのススメ
  • 特別企画
    企業のシステムを支えるOSとエコシステムの全貌
    [特別企画]Red Hat Enterprise Linux 9最新ガイド
  • 短期連載
    今さら聞けないSSH
    [前編]リモートログインとコマンドの実行
  • 短期連載
    MySQLで学ぶ文字コード
    [最終回]文字コードのハマりどころTips集
  • 短期連載
    新生「Ansible」徹底解説
    [4]Playbookの実行環境(基礎編)

おすすめ記事

記事・ニュース一覧