[毎日Kotlin] Day37. Extension function literals
はじめに
毎日Kotlinシリーズです。
このシリーズを初めての方はこちらです。「毎日Kotlin」はじめました | Developers.IO
問題
Function literals with receiver | Try Kotlin
Read about function literals with receiver.
You can declare isEven and isOdd as values, that can be called as extension functions. Complete the declarations below.
fun task(): List<Boolean> { val isEven: Int.() -> Boolean = { TODO() } val isOdd: Int.() -> Boolean = { TODO() } return listOf(42.isOdd(), 239.isOdd(), 294823098.isEven()) }
狙い
ここで考えて欲しい問題の意図はなんだろうか?
今日からDSLの章に突入!Kotlinの豊かな表現力を体感しましょう。
いろんな書き方ができるので、読みやすい、意図が伝わりやすい、書きやすい表現にしましょう。
解答例
fun task(): List<Boolean> { val isEven: Int.() -> Boolean = { this % 2 == 0 } val isOdd: Int.() -> Boolean = { this % 2 == 1 } return listOf(42.isOdd(), 239.isOdd(), 294823098.isEven()) }
isOdd()は記法だけみるとfunかなっと思うのですが、実は無名関数のオブジェクトなんですね。
fun task()内に定義してあるのでfun task()だけで使えます。
別解: fun
素直に実装するならfunで書きますね。
fun isEven(x: Int) = x % 2 == 0 fun isOdd(x: Int) = x % 2 == 1 fun task(): List<Boolean> { return listOf(isOdd(42), isOdd(239), isEven(294823098)) }
別解: 拡張関数
ちょっと便利に呼び出せるように、拡張関数にするのもありですね。
fun task(): List<Boolean> { return listOf(42.isOdd(), 239.isOdd(), 294823098.isEven()) } fun Int.isEven() = this % 2 == 0 fun Int.isOdd() = this % 2 == 1
この関数内のみでつかえるようにしたいなら、関数内で定義することも可能です。
fun task(): List<Boolean> { fun Int.isEven() = this % 2 == 0 fun Int.isOdd() = this % 2 == 1 return listOf(42.isOdd(), 239.isOdd(), 294823098.isEven()) }
別解: 拡張プロパティ
拡張プロパティの書き方もできます。
val Int.isEven: Boolean get() = this % 2 == 0 val Int.isOdd: Boolean get() = this % 2 == 1 fun task(): List<Boolean> { return listOf(42.isOdd, 239.isOdd, 294823098.isEven) }
あとがき
Day38.でまたお会いしましょう。