Kotlin M13で追加されたlateinit試してみた
Kotlin マイルストーン13 がリリースされました!
その中で追加されたlateinitというプロパティにつける修飾子が便利そう。
プロパティの初期化を先延ばしにできるので既存のフレームワークにインジェクトしてもらえるって寸法です。
「プロパティの初期化の先延ばし」っていうとDelegated propertyを思い出すけど、これには問題があったのでした。。
lateinitってDelegates.nonNull()でも同じことできるんじゃないの
— たろう (@ngsw_taro) 2015, 9月 16
@ngsw_taro バイトコード見ると、「private final Lkotlin/properties/ReadWriteProperty; _hello$delegate」ってなってるので、型がちがくてインジェクションしてもらえなくて(´・ω・`)
— しおしお (@_siosio_) December 3, 2014
ということでlateinitを試してみました。
import com.google.inject.Guice
import javax.inject.Inject
import kotlin.properties.Delegates
class Greeter {
fun greet() {
println("Hello")
}
}
class Client {
@Inject
lateinit val greeter1: Greeter
@Inject
val greeter2: Greeter by Delegates.notNull()
}
fun main(args: Array<String>) {
val injector = Guice.createInjector()
val client = injector.getInstance(Client::class.java)
client.greeter1.greet() //=> Hello
client.greeter2.greet() // IllegalStateException thrown
}
Google Guiceでインジェクトしています。
lateinitが付いているgreeter1は見事インジェクトされています!しかし、Delegates.notNull()をつけているgreeter2はインジェクトされておらずgreet()呼び出し時に初期化が済んでないよと例外が投げられてしまいました。
そのほかの変更点についてはまた後ほど。
ちなみにこれならいける
var greeter2: Greeter by Delegates.notNull() @Inject set