Edited at

Kotlin概要からKotlin Coroutinesまで


はじめに

この文章は「Kotlinのざっくりした紹介からCoroutinesの扱いまでざっくり説明してくれない?」という知人の勉強会に赴くにあたり、資料として作成したものです。


Kotlin

Kotlinは2016年2月にJetBrain社がv1.0.0をリリースした、比較的新しい言語です。

v1.0.0リリース以前からいくつかのAndroidアプリで利用され、Google I/O 17にて正式な開発言語になったことから、現在では多くのAndroidアプリ開発で利用されています。


Kotlinを知るためには?


実行環境

Online上でKotlinを試すことができるPlay Kotlinがあります。

そのほか、JetBrain社が提供するIntelliJ IDEA CEAndroid Studioをダウンロードし、手元のPCで動作させることもできます。

どちらも非常に使い勝手が良く、補完機能も非常に強力です。"お試し"から一歩進む際にはぜひ利用してみてください。:hugging:


他の言語とKotlin

公式リファレンスにJavaとの比較が掲載されています。

Javaの文法がわかる方は、一通り目を通すとなんとなーくKotlinがやりたいことが見えてくると思います。

Kotlinは"Kotlin Multiplatform"というプロジェクトでJVMやAndroid OS(こちらもJVMの一種ですが)だけでなく、JavaScriptコードへの変換であるKotlin/JSやiOS上でKotlinのコードが動作するKotlin/Nativeといったプロジェクトを持っています。

このため記述スタイルの違いだけでなく、動作環境の違いまで含めて様々な比較や検討の記事が上がっています。


Kotlinに触れる

Kotlinの書き方については、まずPlay Kotlinに頼るのが良いと思います。

と言うのも、Kotlinの言語仕様でどのような操作が想定されているのかの1次資料であり、かつ読んだその場で手を動かせる機能だからです。

とはいえ、「まずはどんなものか知りたい」程度では億劫かと思いますので、簡単に紹介だけしておきます。


変数の宣言


valvar

valは再代入不可能な宣言、varは再代入可能な宣言です。Javaでいうfinalですね。

Kotlinでは「基本的にはvalで宣言、必要な場合に限ってvarを使う」と考えたほうがシンプルになります。

ただし、valは再代入不可能 であって 不変 ではありません。

Javaにおけるfinal宣言を行ったクラスのインスタンスでも、内部のフィールドを書き換えることは可能、と同じと考えてしまえば簡単です。

class ClassA {

var name = "Yamada Taro"
}

class ClassB {
private val nameObj: ClassA = ClassA()

fun functionB() {
nameObj.name = "Yamada Hanako" // 代入可能
}
}


型推論

Kotlinは型推論があります。

そのため変数の宣言時に型が明らかな場合には、型の宣言を省略することができます。

private val num: Int = 42 // OK

private val num = 42 // OK

一方で、Javaと異なり初期化時に変数名だけ宣言することは(いくつかのテクニックはありますが)できません。

class Test1 {

private val num: Int

fun initMethod() {
num = 42 // NG
}
}


リスト

Kotlinにはリスト(List)と配列(Array)が用意されています。

このうち、リストは再代入不可能なリスト(List)と再代入可能なリスト(MutableList)の2つに分けられています。

再代入不可能なリストを効率よく使うためには、リスト操作のメソッドが欠かせません。

KotlinにはJava8のようなリスト操作用の便利なメソッドが標準で用意されています。

下記にあげるもの以外にもありますし、Kotlin Extentionの仕組みを使えば、即席でリスト操作用のメソッドを作ることもできます。


filter

ref https://play.kotlinlang.org/byExample/05_stdlib/03_filter

val numbers = listOf(1, -2, 3, -4, 5, -6)      // [1, -2, 3, -4, 5, -6]

val positives = numbers.filter { x -> x > 0 } // [1, 3, 5]
val negatives = numbers.filter { it < 0 } // [-2, -4, -6]


map

ref https://play.kotlinlang.org/byExample/05_stdlib/04_map

val numbers = listOf(1, -2, 3, -4, 5, -6)     // [1, -2, 3, -4, 5, -6]

val doubled = numbers.map { x -> x * 2 } // [2, -4, 6, -8, 10, -12]
val tripled = numbers.map { it * 3 } // [3, -6, 9, -12, 15, -18]


first、last

ref https://play.kotlinlang.org/byExample/05_stdlib/07_firstlast

val numbers = listOf(1, -2, 3, -4, 5, -6)

val first = numbers.first() // 1
val last = numbers.last() // -6

val firstEven = numbers.first { it % 2 == 0 } // -2
val lastOdd = numbers.last { it % 2 != 0 } // 5


Kotlin Coroutines

Kotlin 1.3よりKotlin Coroutinesが正式にリリースされました。

Kotlin 1.3 Released with Coroutines, Kotlin/Native Beta, and more

Kotlin Coroutinesの概要は、公式ページや動画を見ることをお勧めします。

あと、sys1yagi先生による下記2ブログは必読です。

※Coroutine Contextについては特に文献や解説を調べることをお勧めします。


AndroidにおけるKotlin Coroutines

Androidアプリ開発において、一般にバックグラウンドで行われるべき処理 -ネットワークやDBアクセス、画像処理など- でKotlin Coroutinesが使われる傾向にあります。

特にサーバーAPIへのアクセス処理を書く際に、デファクトスタンダードとなっているRetforitRetrofit用のAdapterが作成されているため、導入しやすく効果も感じやすくなっています。

Android Jetpackにて、Roomライブラリもsuspendに対応するようなので、DB周りにももっと期待が持てる状態になっています。


Coroutine Contextについて

Android Jetpackに含まれるktxにおいて、ViewModelで利用することを想定したCoroutine Contextの実装が用意されつつあります。

Activity/Fragment、それにViewModelにおいて公式の解説通りにCoroutine Contextを実装すれば、まず想定外のリークを避けた開発が可能になっています。


サーバーにおけるKotlin Coroutines

※筆者はAndroidアプリメインなので、概略程度です

Creating a RESTful Web Service with Spring Bootにて紹介されているようにサーバーサイドの言語してもKotlinは開発されています。

サーバーサイドではAndroidアプリよりも並行で処理することが多く要求される(と思います)。

その際に参考になりそうなのが、下記のリファレンスです。


Coroutine Contextについて

Kotlinを利用するフレームワークに合わせたCoroutine Contextの実装を選択する必要があります。

公式にサポートされていれば、推奨される実装方法があるはずなので必ずチェックしましょう。