この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
毎日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.でまたお会いしましょう。