Share
Embed
Transcript
34 slides
-
Copyright © Sansan, Inc. All rights reserved. > KotlinでPhantom Type
第2回Kotlin勉強会 @Sansan #kotlin_̲sansan 2016. 3. 24 @boohbah -
Copyright © Sansan, Inc. All rights reserved. > ⾃自⼰己紹介 -
⼭山本純平 - Sansan株式会社 Eight事業部 - EightのAndroidアプリの開発 - twitter: @boohbah - github: https://github.com/yamamotoj -
Copyright © Sansan, Inc. All rights reserved. > Eightの新機能「オンライン名刺刺交換」 -
もう紙の名刺刺はいらない! - NearByで周囲のEightユー ザーを検索索 - 複数のユーザー間でも名刺刺 交換ができる -
Copyright © Sansan, Inc. All rights reserved. > Phantom Type
(༓ྶܕ) - Πϯελϯεͷঢ়ଶΛܕύϥϝʔλͰ࣋ͭ͜ͱʹΑͬ ͯɺঢ়ଶͷνΣοΫΛίϯύΠϧ࣌ʹߦ͏ɻ - ঢ়ଶΛද͢ܕύϥϝʔλ࣮ࡍʹΘΕΔ͜ͱ͕ͳ ͘ɺίϯύΠϧ࣌ʹফ͑ͯ͠·͏ɻ -
Copyright © Sansan, Inc. All rights reserved. > 実際に⾒見見てみましょう sealed
class State { class NotReady : State() class Ready : State() } data class Data<T : State>(val a: Int) { } これが Phantom Type 型パラメータは実⾏行行時に消 去されるため、Stateクラ スが使⽤用されることはない -
Copyright © Sansan, Inc. All rights reserved. > 引数で振り分け fun
show(data :Data<NotReady>) = print(“Not ready!!”) fun show(data: Data<Ready>) = print(“ready!!”) fun bar(data: Data<Ready>) = print(“bar!”) val d1 = Data<NotReady>(2) show(d1) // -‐> Not ready!! bar(d1) // ίϯύΠϧΤϥʔ val d2 = Data<Ready>(2) show(d2) // -‐> ready !! bar(d2) // -‐> bar! -
Copyright © Sansan, Inc. All rights reserved. > 拡張関数と併⽤用する fun
Data<State.NotReady>.ready() = Data<State.Ready>(a) fun Data<State.Ready>.say() = print(“I’m ready!!”) val d1 = Data<State.NotReady>(2) val d2 = d1.ready() // Data<State.Ready> d1.say() // ίϯύΠϧΤϥʔ d2.ready() // ίϯύΠϧΤϥʔ d2.say() // -‐> I;m ready!! d1 == d2 // True -
Copyright © Sansan, Inc. All rights reserved. > 例例えば簡単なSQL⽂文を出⼒力力するDSLを考えてみる Query
.select("*") .from("Person") .where("ID = 1") .print() // -‐> SELECT * FROM Person WHERE ID = 1; -
Copyright © Sansan, Inc. All rights reserved. > クラスと状態の定義 //
-‐> SELECT * FROM Person WHERE ID = 1; sealed class Status { class From : Status() // From۟ΛೖྗͰ͖Δঢ়ଶ class Where : Status() // Where۟ΛೖྗͰ͖Δঢ়ଶ class Print : Status() // ݁ՌΛग़ྗͰ͖Δঢ়ଶ } // QueryੜΫϥεͷఆٛ class Query<T : Status>( val column: String, val tableName: String, val predicate: String) -
Copyright © Sansan, Inc. All rights reserved. > メソッドの定義 class
Query<T : Status>( val column: String, val tableName: String, val predicate: String) { } -
Copyright © Sansan, Inc. All rights reserved. > メソッドの定義 class
Query<T : Status>( val column: String, val tableName: String, val predicate: String) { companion object { fun select(column: String) = Query<Status.From>(column, "", "") } } Query<Status.From>型 のオブジェクトを⽣生成 -
Copyright © Sansan, Inc. All rights reserved. > メソッドの定義 class
Query<T : Status>( val column: String, val tableName: String, val predicate: String) { companion object { fun select(column: String) = Query<Status.From>(column, "", "") } } fun Query<Status.From>.from(tableName: String) = Query<Status.Where>(this.column, tableName, this.predicate) Query<Status.Where>型 のオブジェクトを⽣生成 Query<Status.From>型 からしか呼び出せない -
Copyright © Sansan, Inc. All rights reserved. > メソッドの定義 class
Query<T : Status>( val column: String, val tableName: String, val predicate: String) { companion object { fun select(column: String) = Query<Status.From>(column, "", "") } } fun Query<Status.From>.from(tableName: String) = Query<Status.Where>(this.column, tableName, this.predicate) fun Query<Status.Where>.where(predicate: String) = Query<Status.Print>(this.column, this.tableName, predicate) Query<Status.Print>型のオブジェクトを⽣生成 Query<Status.Where>型 からしか呼び出せない -
Copyright © Sansan, Inc. All rights reserved. > メソッドの定義 class
Query<T : Status>( val column: String, val tableName: String, val predicate: String) { companion object { fun select(column: String) = Query<Status.From>(column, "", "") } } fun Query<Status.From>.from(tableName: String) = Query<Status.Where>(this.column, tableName, this.predicate) fun Query<Status.Where>.where(predicate: String) = Query<Status.Print>(this.column, this.tableName, predicate) fun Query<Status.Print>.print() = "SELECT $column FROM $tableName WHERE $predicate ;" Query<Status.Print>型 からしか呼び出せない -
Copyright © Sansan, Inc. All rights reserved. > 結果 Query
.select(“*”) // Query<Status.From> .from(“Person") // Query<Status.Where> .where("ID = 1”) // Query<Status.Print> .print() // -‐> SELECT * FROM Person WHERE ID = 1; -
Copyright © Sansan, Inc. All rights reserved. > まとめ -
Kotlinでも型レベルプログラミング! -
Copyright © Sansan, Inc. All rights reserved. > お気に⼊入りの拡張関数 fun
<T : Any> T.log( tag: String = "my-‐debug", to_string: (T) -‐> String = { it.toString() } ): T { Log.d(tag, to_string(this)) return this } -
Copyright © Sansan, Inc. All rights reserved. > お気に⼊入りの拡張関数 fun
<T : Any> T.log( tag: String = "my-‐debug", to_string: (T) -‐> String = { it.toString() } ): T { Log.d(tag, to_string(this)) return this } fun getHoge() = A().let{ transform(it) }.B() -
Copyright © Sansan, Inc. All rights reserved. > お気に⼊入りの拡張関数 fun
<T : Any> T.log( tag: String = "my-‐debug", to_string: (T) -‐> String = { it.toString() } ): T { Log.d(tag, to_string(this)) return this } fun getHoge() = A().log().let{ transform(it) }.B() Single Expression形式でもlogを出せる -
Copyright © Sansan, Inc. All rights reserved. > お気に⼊入りの拡張関数 fun
<T : Any> T.log( tag: String = "my-‐debug", to_string: (T) -‐> String = { it.toString() } ): T { Log.d(tag, to_string(this)) return this } fun getHoge() = A().log(){ “a:” + it.toString() } .let{ transform(it) }.B() 任意の⽂文字列列に変換可能 -
Copyright © Sansan, Inc. All rights reserved. > お気に⼊入りの拡張関数 fun
<T : Any> T.log( tag: String = "my-‐debug", to_string: (T) -‐> String = { it.toString() } ): T { Log.d(tag, to_string(this)) return this } fun getHoge() = A().log(“my_tag”){ “a: $it” } .let{ transform(it) }.B() タグも変更更できる -
Copyright © Sansan, Inc. All rights reserved. > Raw Textリテラル便便利利
val json = """ { "name": yamamotoj, "url": "https://github.com/yamamotoj", } """ // Java String json = "{\n" + " \"name\": yamamotoj,\n" + " \"url\": \"https://github.com/yamamotoj\",\n" + "}\n"; -
$PQZSJHIU4BOTBO *OD"MMSJHIUTSFTFSWFE 4BOTBOҰॹʹ৽͍͠ՁΛ࡞͍ͬͯ͘ ؒΛ͕͍ͯ͞͠·͢ɻ 3VCZ 3VCZPO3BJMT ʢ8FCΞϓϦέʔγϣϯʣ $ɼ"41/&5.7$ ʢ8FCΞϓϦέʔγϣϯʣ
J04"OESPJEΞϓϦ ݸਓ໊͚ཧΞϓϦʮ&JHIUʯ ໊σʔλԽࢄॲཧγεςϜ ๏ਓ໊͚ཧαʔϏεʮ4BOTBOʯ ๏ਓ໊͚ཧαʔϏε ʮ4BOTBOʯ ݸਓ໊͚ཧΞϓϦʮ&JHIUʯ ΤϯδχΞืूத 4BOTBO࠾༻ ݕࡧ SFDSVJU!TBOTBODPN·Ͱ ͓ؾܰʹ͝࿈བྷ͍ͩ͘͞ɻ ڵຯͷ͋Δํ