Slide 1

Slide 1 text

広く浅く語るKotlinの魅力 2017-07-24 長澤 太郎 @ngsw_taro

Slide 2

Slide 2 text

もくじ 1. Kotlin概要と誕生の背景 2. コードベースをスリムにするKotlinのGood Parts 3. バグの作り込みを防ぐKotlinのGood Parts 4. Kotlin界隈の未来

Slide 3

Slide 3 text

自己紹介 ● 長澤 太郎(たろーって呼んでね) ● @ngsw_taro ● エムスリー株式会社 ● やすべえとディズニーが大好き!

Slide 4

Slide 4 text

(事実上の)Kotlinエバンジェリスト ● 日本Kotlinユーザグループ代表 ● 講演実績 ○ DroidKaigi 2015, 2016, 2017 ○ JJUG CCC 2015 Fall ○ Hacker Tackle 2016 ○ Lightweight Language of Things など ● 執筆実績 ○ Kotlinスタートブック ○ 日経ソフトウエア ○ Software Design ○ I/O など

Slide 5

Slide 5 text

1. Kotlin概要と誕生の背景

Slide 6

Slide 6 text

Q. Kotlinとは?

Slide 7

Slide 7 text

Q. Kotlinとは? A. プログラミング言語のひとつ

Slide 8

Slide 8 text

Q. Kotlinとは? A. プログラミング言語のひとつ ● 静的型付けオブジェクト指向言語 ● いわゆる「JVM言語」 ● 開発元: JetBrains ● 2016年2月に正式リリース ● Apache License ver2.0

Slide 9

Slide 9 text

Q. Kotlinとは? A. プログラミング言語のひとつ ● 静的型付けオブジェクト指向言語 ● いわゆる「JVM言語」 ● 開発元: JetBrains ● 2016年2月に正式リリース ● Apache License ver2.0 静的型付け: プログラムの実行前(コンパイル時)に型が決まる オブジェクト指向: Javaと同じく対象物(オブジェクト)に着目してプログラ ムを組み上げる

Slide 10

Slide 10 text

Q. Kotlinとは? A. プログラミング言語のひとつ ● 静的型付けオブジェクト指向言語 ● いわゆる「JVM言語」 ● 開発元: JetBrains ● 2016年2月に正式リリース ● Apache License ver2.0 Java仮想マシン(JVM)の上で動作する「Javaバイトコード」 にコンパイルされるようなプログラミング言語 JavaScriptやLLVMもターゲットに!?

Slide 11

Slide 11 text

Q. Kotlinとは? A. プログラミング言語のひとつ ● 静的型付けオブジェクト指向言語 ● いわゆる「JVM言語」 ● 開発元: JetBrains ● 2016年2月に正式リリース ● Apache License ver2.0 統合開発環境 IntelliJ IDEAの開発元の会社。 Googleと共同で財団の設立。 大きな後ろ盾があることを意味する。

Slide 12

Slide 12 text

Q. Kotlinとは? A. プログラミング言語のひとつ ● 静的型付けオブジェクト指向言語 ● いわゆる「JVM言語」 ● 開発元: JetBrains ● 2016年2月に正式リリース ● Apache License ver2.0 新しい言語です!現在 ver1.1.3-2

Slide 13

Slide 13 text

Q. Kotlinとは? A. プログラミング言語のひとつ ● 静的型付けオブジェクト指向言語 ● いわゆる「JVM言語」 ● 開発元: JetBrains ● 2016年2月に正式リリース ● Apache License ver2.0 オープンソースです。 ソースコードを自由に入手・改造できる!

Slide 14

Slide 14 text

Q. JVM言語?

Slide 15

Slide 15 text

Q. JVM言語? A. JVMサイコーだけどJava言語はチョット...

Slide 16

Slide 16 text

Q. JVM言語? A. JVMサイコーだけどJava言語はチョット... ● 冗長、ボイラープレートの嵐 ● nullポインタのデリファレンス問題 ● 後方互換性の維持 ○ 古い文法が存在する ○ 型安全性に問題あり

Slide 17

Slide 17 text

Q. JVM言語? A. JVMサイコーだけどJava言語はチョット... ● 冗長、ボイラープレートの嵐 ● nullポインタのデリファレンス問題 ● 後方互換性の維持 ○ 古い文法が存在する ○ 型安全性に問題あり いろんなところで動いている。 JVM用コード(Javaコード)がたくさんある。 歴史長い。強い。

Slide 18

Slide 18 text

Q. JVM言語? A. JVMサイコーだけどJava言語はチョット... ● 冗長、ボイラープレートの嵐 ● nullポインタのデリファレンス問題 ● 後方互換性の維持 ○ 古い文法が存在する ○ 型安全性に問題あり 書かなきゃいけないコードが無駄に多い。

Slide 19

Slide 19 text

Q. JVM言語? A. JVMサイコーだけどJava言語はチョット... ● 冗長、ボイラープレートの嵐 ● nullポインタのデリファレンス問題 ● 後方互換性の維持 ○ 古い文法が存在する ○ 型安全性に問題あり めっちゃバグるんですけど。 そもそもの言語仕様がアレなのでは。

Slide 20

Slide 20 text

Q. JVM言語? A. JVMサイコーだけどJava言語はチョット... ● 冗長、ボイラープレートの嵐 ● nullポインタのデリファレンス問題 ● 後方互換性の維持 ○ 古い文法が存在する ○ 型安全性に問題あり 今は使うべきでない文法が存在する。 削除してくれればいいのに...そういうわけにも。

Slide 21

Slide 21 text

Q. なんでKotlin?

Slide 22

Slide 22 text

Q. なんでKotlin? A. いいこといっぱいだから!

Slide 23

Slide 23 text

Q. なんでKotlin? A. いいこといっぱいだから! ● Javaよりも安全、簡潔なコードを書ける ● Javaエンジニアにとって、学習コストが低そう ○ 精神的なハードルもやや低めっぽい ● JetBrains/Googleの後ろ盾がある ● JSへのトランスパイル、実験段階だけどLLVM

Slide 24

Slide 24 text

2. コードベースをスリムにする KotlinのGood Parts

Slide 25

Slide 25 text

Extension 既存のクラスやインタフェースを変更せずに、新たにメソッドやプ ロパティを追加するような機能。 fun String.hello() { println("Hello, $this!") } "world".hello()

Slide 26

Slide 26 text

Extension 既存のクラスやインタフェースを変更せずに、新たにメソッドやプ ロパティを追加するような機能。 fun String.hello() { println("Hello, $this!") } "world".hello() Stringに対して 拡張関数を定義 メソッドのように呼 び出せる

Slide 27

Slide 27 text

Extension 既存のクラスやインタフェースを変更せずに、新たにメソッドやプ ロパティを追加するような機能。 fun String.hello() { println("Hello, $this!") } "world".hello() thisでレシーバ を参照できる

Slide 28

Slide 28 text

Extension 既存のクラスやインタフェースを変更せずに、新たにメソッドやプ ロパティを追加するような機能。 fun String.hello() { println("Hello, $this!") } "world".hello() Stringテンプレート

Slide 29

Slide 29 text

拡張プロパティ val Int.isEven: Boolean get() = this % 2 == 0 123.isEven //=> false

Slide 30

Slide 30 text

拡張プロパティ val Int.isEven: Boolean get() = this % 2 == 0 123.isEven //=> false Intに対する 拡張プロパティ

Slide 31

Slide 31 text

プロパティ ● オブジェクトの性質・属性などを表す ● Javaのフィールドのようにアクセス可能 ● しかし実装は自在

Slide 32

Slide 32 text

プロパティの例 class Name { var value: String = "" get() = field set(newValue) { field = newValue } val length: Int get() = value.length } name.value = "Taro" name.length //=> 4

Slide 33

Slide 33 text

プロパティの例 class Name { var value: String = "" get() = field set(newValue) { field = newValue } val length: Int get() = value.length } name.value = "Taro" name.length //=> 4 変更可能な プロパティvalue 変更不可能な プロパティlength こんな感じで使える

Slide 34

Slide 34 text

プロパティの例 class Name { var value: String = "" get() = field set(newValue) { field = newValue } val length: Int get() = value.length } name.value = "Taro" name.length //=> 4 取得時の実装 取得時の実装 セット時の実装

Slide 35

Slide 35 text

プロパティの例 class Name { var value: String = "" get() = field set(newValue) { field = newValue } val length: Int get() = value.length } name.value = "Taro" name.length //=> 4 暗黙の変数 field 暗黙の変数 field 初期値必須

Slide 36

Slide 36 text

プロパティの例 class Name { var value: String = "" get() = field set(newValue) { field = newValue } val length: Int get() = value.length } name.value = "Taro" name.length //=> 4 省略OK

Slide 37

Slide 37 text

データクラス データを表現するクラスを簡単に定義するための仕組み。 便利なメソッドが自動生成される。 data class Person( val id: Long, val name: String )

Slide 38

Slide 38 text

データクラスが提供する便利なメソッド val taro = Person(id=5, name="Taro") taro.toString() //=> Person(id=5, name=Taro) taro == Person(id=5, name="Taro") //=> true val jiro = taro.copy(name="Jiro") val (id, name) = jiro id //=> 5 name //=> Jiro

Slide 39

Slide 39 text

データクラスが提供する便利なメソッド val taro = Person(id=5, name="Taro") taro.toString() //=> Person(id=5, name=Taro) taro == Person(id=5, name="Taro") //=> true val jiro = taro.copy(name="Jiro") val (id, name) = jiro id //=> 5 name //=> Jiro 名前付き引数

Slide 40

Slide 40 text

データクラスが提供する便利なメソッド val taro = Person(id=5, name="Taro") taro.toString() //=> Person(id=5, name=Taro) taro == Person(id=5, name="Taro") //=> true val jiro = taro.copy(name="Jiro") val (id, name) = jiro id //=> 5 name //=> Jiro toStringメソッドの実装が自動生成される

Slide 41

Slide 41 text

データクラスが提供する便利なメソッド val taro = Person(id=5, name="Taro") taro.toString() //=> Person(id=5, name=Taro) taro == Person(id=5, name="Taro") //=> true val jiro = taro.copy(name="Jiro") val (id, name) = jiro id //=> 5 name //=> Jiro equalsメソッドの実装が自動生成される

Slide 42

Slide 42 text

データクラスが提供する便利なメソッド val taro = Person(id=5, name="Taro") taro.toString() //=> Person(id=5, name=Taro) taro == Person(id=5, name="Taro") //=> true val jiro = taro.copy(name="Jiro") val (id, name) = jiro id //=> 5 name //=> Jiro コピーメソッド

Slide 43

Slide 43 text

データクラスが提供する便利なメソッド val taro = Person(id=5, name="Taro") taro.toString() //=> Person(id=5, name=Taro) taro == Person(id=5, name="Taro") //=> true val jiro = taro.copy(name="Jiro") val (id, name) = jiro id //=> 5 name //=> Jiro 中身を分解して取得可能

Slide 44

Slide 44 text

3. バグの作り込みを防ぐ KotlinのGood Parts

Slide 45

Slide 45 text

Null安全 ● nullの可能性のあるものと、そうでないものを厳格に 区別することでケアレスミスを防ぐ ● nullの可能性のない型(NotNull) ● nullの可能性のある型(Nullable) ?をつけて表現 val a: Int = null // コンパイルエラー val b: Int? = null // OK b.toString() // コンパイルエラー

Slide 46

Slide 46 text

Nullableの扱いは、とことん慎重に val s: String? = getString() s.length // コンパイルエラー これを許してしまうと NPEの原因になる

Slide 47

Slide 47 text

if文などによるnullチェック if (s != null) { s.length } nullでないことが保証される文脈 ではNotNullとして扱える

Slide 48

Slide 48 text

安全呼び出し s?.length if (s != null) s.length else null 同じ if-elseは式 (評価されて値になる)

Slide 49

Slide 49 text

安全呼び出し s?.length if (s != null) s.length else null 同じ if-elseは式 (評価されて値になる) foo?.bar()?.baz()?.qux() メソッドチェーンで役立つ

Slide 50

Slide 50 text

拡張関数 let fun T.let(f: (T)->R): R = f(this)

Slide 51

Slide 51 text

拡張関数 let fun T.let(f: (T)->R): R = f(this) ● 任意の型Tの拡張関数

Slide 52

Slide 52 text

拡張関数 let fun T.let(f: (T)->R): R = f(this) ● 任意の型Tの拡張関数 ● 戻り値の型は、任意の型R

Slide 53

Slide 53 text

拡張関数 let fun T.let(f: (T)->R): R = f(this) ● 任意の型Tの拡張関数 ● 戻り値の型は、任意の型R ● 引数fは「Tを引数に取ってRを返す」関数

Slide 54

Slide 54 text

拡張関数 let fun T.let(f: (T)->R): R = f(this) ● 任意の型Tの拡張関数 ● 戻り値の型は、任意の型R ● 引数fは「Tを引数に取ってRを返す」関数 ● 引数としてthisを渡してfを呼び出し、その戻り値をそのまま 返す

Slide 55

Slide 55 text

拡張関数 let fun T.let(f: (T)->R): R = f(this) ● 任意の型Tの拡張関数 ● 戻り値の型は、任意の型R ● 引数fは「Tを引数に取ってRを返す」関数 ● 引数としてthisを渡してfを呼び出し、その戻り値をそのまま 返す val got = "I love Kotlin".let { s -> s.toLowerCase() } got //=> "i love kotlin"

Slide 56

Slide 56 text

拡張関数 let fun T.let(f: (T)->R): R = f(this) ● 任意の型Tの拡張関数 ● 戻り値の型は、任意の型R ● 引数fは「Tを引数に取ってRを返す」関数 ● 引数としてthisを渡してfを呼び出し、その戻り値をそのまま 返す val got = "I love Kotlin".let { s -> s.toLowerCase() } got //=> "i love kotlin" ラムダ式を渡す

Slide 57

Slide 57 text

拡張関数 let fun T.let(f: (T)->R): R = f(this) ● 任意の型Tの拡張関数 ● 戻り値の型は、任意の型R ● 引数fは「Tを引数に取ってRを返す」関数 ● 引数としてthisを渡してfを呼び出し、その戻り値をそのまま 返す val got = "I love Kotlin".let { s -> s.toLowerCase() } got //=> "i love kotlin"

Slide 58

Slide 58 text

安全呼び出し + 拡張関数let val messag: String? = getMessage() val got: String = message?.let { s -> s.toLowerCase() }

Slide 59

Slide 59 text

安全呼び出し + 拡張関数let val messag: String? = getMessage() val got: String = message?.let { s -> s.toLowerCase() } messageがnullだったら これ以降の呼び出しは行われない

Slide 60

Slide 60 text

安全呼び出し + 拡張関数let val messag: String? = getMessage() val got: String = message?.let { s -> s.toLowerCase() } messageがnullでなければ この中が実行される

Slide 61

Slide 61 text

複数のNullableをNotNullに→素直にifで if (foo != null && bar != null) { foo.execute(bar) } foo?.let { f -> bar?.let { b -> f.execute(b) } } ◎よい例 ✖ダメな例(必要以上にネストが深くなる)

Slide 62

Slide 62 text

Nullableに関する演算子 val a: String = b ?: "default" val a: String = b!! エルビス演算子 !!演算子

Slide 63

Slide 63 text

Nullableに関する演算子 val a: String = b ?: "default" val a: String = b!! エルビス演算子 !!演算子 b != null -> b b == null -> "default"

Slide 64

Slide 64 text

Nullableに関する演算子 val a: String = b ?: "default" val a: String = b!! エルビス演算子 !!演算子 禁断のNotNull強制変換 絶対に使わないこと! どうしても強制変換したい場合はrequireNotNull関数を使用する。

Slide 65

Slide 65 text

4. Kotlin界隈の未来

Slide 66

Slide 66 text

今後のKotlin界隈 ● Kotlinに対する過度の期待からの勢い導入 ● そして、失敗。挫折。 ○ 拡張関数、演算子オーバロード、委譲プロパティの濫用とか ○ Javaとの相互運用に関して ○ コーディング規約、コードレビュー、学習コスト ● 銀の弾丸はない。適切な道具を適切に使うこと。 ● 数年で「ブーム」から「定番」に移行

Slide 67

Slide 67 text

今後の日本Kotlinユーザグループ ● JKUG主導イベントをもっと開催したい ● 運営体制の強化(メンバー増員、運営定例会) ● 1Day カンファレンスを計画中!

Slide 68

Slide 68 text

今後のKotlinエバンジェリスト ● 泥臭く真面目に活動(講演・執筆など) ● スケールしやすい形での貢献 ○ 書籍の監修 ○ 技術顧問(レビューやペアプロ、指導など)

Slide 69

Slide 69 text

まとめ ● JVMは魅力的だがJava言語に課題感を持っていた→JVM言 語の台頭→Kotlin誕生 ● Javaよりもコードベースをスリムに保つ ○ 例)Extension, データクラス、プロパティ ● NullPointerExceptionを発生させない仕組み ○ Null安全 ○ 扱い安さの工夫: 安全呼び出し、エルビス演算子、拡張関数let ● 今はKotlinブームだがそのうち定番になる