Slide 1

Slide 1 text

Kotlin v1.3 
 Update Features 2018-11-01 MixLeap - Kotlin Conf 2018 Recap - @bulbulpaul

Slide 2

Slide 2 text

About me !2 おかだ のぶお ポール@bulbulpaul Yahoo!カレンダー Backend Engineer Python, Kotlin, Rust name: : service: job: lang:

Slide 3

Slide 3 text

#mixleap

Slide 4

Slide 4 text

Kotlin v1.3

Slide 5

Slide 5 text

#mixleap Kotlin v1.3 Features • Coroutine • Experimental Features • Kotlin Native Beta • Other Update !5

Slide 6

Slide 6 text

#mixleap Kotlin v1.3 Features • Coroutine • Experimental Features • Kotlin Native Beta • Other Update !6

Slide 7

Slide 7 text

Coroutine

Slide 8

Slide 8 text

#mixleap Coroutine Import kotlin.coroutines.experimental. !8 *

Slide 9

Slide 9 text

#mixleap Coroutine Import kotlin.coroutines.experimental. !9 *

Slide 10

Slide 10 text

#mixleap What’s Coroutine A coroutine can be thought of as an instance of suspendable computation, i.e. the one that can suspend at some points and later resume execution possibly on another thread. Coroutines calling each other (and passing data back and forth) can form the machinery for cooperative multitasking. !10 Ҿ༻: https://github.com/Kotlin/KEEP/blob/master/proposals/coroutines.md 中断可能な計算インスタンス

Slide 11

Slide 11 text

#mixleap What’s Coroutine • 中断可能な計算インスタンス
 → ざっくり⾔うと軽量なスレッド • 特徴のスレッドに依存しない • 昨年のKotlinConfで「実質Stableだよ」発⾔ !11

Slide 12

Slide 12 text

#mixleap What’s Coroutine • 中断可能な計算インスタンス
 → ざっくり⾔うと軽量なスレッド • 特徴のスレッドに依存しない • 昨年のKotlinConfで「実質Stableだよ」発⾔
 → まさかの仕様変更!! !12

Slide 13

Slide 13 text

#mixleap 中断/再開 launch {
 val event = async { getEvent(id)} .await()
 saveEvent(event)
 } !13  ⾃分は中断して別のcoroutineを起動して  結果を受け取ったら再開する

Slide 14

Slide 14 text

#mixleap 中断/再開 launch {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !14

Slide 15

Slide 15 text

#mixleap 中断/再開 launch {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !15

Slide 16

Slide 16 text

#mixleap 中断/再開 launch {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !16

Slide 17

Slide 17 text

#mixleap 中断/再開 launch {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !17 実⾏をキャンセル

Slide 18

Slide 18 text

#mixleap 中断/再開 launch {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !18 実⾏をキャンセル キャンセル??

Slide 19

Slide 19 text

#mixleap 中断/再開 launch {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !19 実⾏をキャンセル ⽌まらない!!

Slide 20

Slide 20 text

#mixleap 中断/再開 launch {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.awaint().also {
 //save
 }
 } !20 Deprecated

Slide 21

Slide 21 text

Coroutine Scope

Slide 22

Slide 22 text

#mixleap Coroutine Scope • コルーチンのスコープを定義する • ⾃動的にコンテキスト要素とキャンセルの両⽅を
 伝播させる事が可能 !22

Slide 23

Slide 23 text

#mixleap 中断/再開 coroutineScope {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !23

Slide 24

Slide 24 text

#mixleap 中断/再開 coroutineScope {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !24 実⾏をキャンセル

Slide 25

Slide 25 text

#mixleap 中断/再開 coroutineScope {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !25 実⾏をキャンセル キャンセルされる

Slide 26

Slide 26 text

#mixleap 中断/再開 coroutineScope {
 val localEvent = async { getEvent(id)}
 val remoteEvent = async { saveEvent(event)}
 localEvent.await() ?: remoteEvent.await().also {
 //save
 }
 } !26 実⾏をキャンセル キャンセルされる

Slide 27

Slide 27 text

#mixleap もっと知りたい⽅は… • Kotlin Festの⼋⽊さんのセッションは⾮常にわかりやすい • https://speakerdeck.com/sys1yagi/kotlin-korutinwo-li- jie-siyou !27

Slide 28

Slide 28 text

Experimental Features

Slide 29

Slide 29 text

#mixleap Experimental • Contracts • Inline class • Experimental API !29

Slide 30

Slide 30 text

#mixleap Experimental • Contracts • Inline class • Experimental API !30

Slide 31

Slide 31 text

#mixleap What’s Contracts?? Support a way to explicitly express some aspects of function's behavior, thus allowing programmers to cooperate with Kotlin compiler by providing it with additional guarantees, getting more complete and intense analysis in return. !31 関数の振る舞いをコンパイラに伝える仕組み

Slide 32

Slide 32 text

#mixleap Contracts • Calls In Place
 →この処理は「⼀回実⾏される」「⼀回以上実⾏される」 等の情報をコンパイラへ伝える • Returns
 →返り値の戻り条件等をコンパイラへ伝える !32

Slide 33

Slide 33 text

#mixleap Contracts !33 fun main(){
 val s: String? = ""
 if(!s.isNullOrEmpty()) {
 s.first()
 }
 }

Slide 34

Slide 34 text

#mixleap Contracts !34 fun main(){
 val s: String? = ""
 if(!s.isNullOrEmpty()) {
 s.first() //ここでコンパイルエラー
 }
 }

Slide 35

Slide 35 text

#mixleap Contracts !35 public inline fun CharSequence?.isNullOrEmpty(): Boolean{
 contract{
 returns(false) implies (this@isNullOrEmpty != null)
 }
 return this == null || this.length == 0
 } Kotlin v1.3での実装

Slide 36

Slide 36 text

#mixleap Contracts !36 public inline fun CharSequence?.isNullOrEmpty(): Boolean{
 contract{
 returns(false) implies (this@isNullOrEmpty != null)
 }
 return this == null || this.length == 0
 } コンパイラにfalse時のNullじゃない事を教えてる

Slide 37

Slide 37 text

#mixleap Contracts !37 fun main(){
 val s: String? = ""
 if(!s.isNullOrEmpty()) {
 s.first() // 実⾏可能
 }
 }

Slide 38

Slide 38 text

Inline class

Slide 39

Slide 39 text

#mixleap inline class • インライン展開されるクラス • Primary constructorにread only なプロパティを持つ • Backing fieldを持つプロパティは定義できない • ===で⽐較不可能 • initialization blockが持てない • SuccessOrFailure Resultで使われている !39

Slide 40

Slide 40 text

#mixleap inline class inline class Hours(val value: Int) {
 fun toMinutes() = value * 60
 } fun main() {
 val hour = Hours(3)
 println(hour.toMinutes()) 
 } !40

Slide 41

Slide 41 text

#mixleap inline class // 現時点でenumはinline化できない
 inline enum class Unit {
 SECONDS_PER_MINUTE(60),
 MINUTES_PER_HOUR(60),
 HOURS_PER_DAY(24)
 } !41

Slide 42

Slide 42 text

More Update

Slide 43

Slide 43 text

#mixleap 細かなUpdate • whenの()内で変数宣⾔が可能に • annotation classがネストして宣⾔可能に • 符号なし整数型が追加 • Collection, Map Array, SequenceにifEmptyが追加 • main()が引数がオプションに変更 • and more !43

Slide 44

Slide 44 text

まとめ

Slide 45

Slide 45 text

#mixleap まとめ • Coroutineがやっとstableに • Experimentalの活⽤は慎重に… • Kotlinらしいコードが書きやすくなった • 今年〜来年にかけて1.3対応したライブラリがふえるのでは • Contracts等でORM等のNullSafeじゃなかったところも変わるかもしれない • とりあえずv1.3へ上げて楽しくKotlin書きましょう! !45

Slide 46

Slide 46 text

Have a nice Kotlin!