はじめに
公式の問題集「Kotlin Koans」を解きながらKotlinを学習します。
過去記事はこちら
- Introduction
- Classes
問題
extension functionsについて学びます。そして、extension functionsInt.r()
とPair.r()
を実装して、Int
とPair
をRationalNumber
に変換するようにします。
Pair
は標準ライブラリで定義されているクラスです
data class Pair<out A, out B>(
val first: A,
val second: B
)
修正前のコード
fun Int.r(): RationalNumber = TODO()
fun Pair<Int, Int>.r(): RationalNumber = TODO()
data class RationalNumber(val numerator: Int, val denominator: Int)
問題のポイント
拡張関数を宣言するには レシーバタイプ (receiver type) を関数名の前に付ける必要があります。 次の例では、 swap 関数を MutableList に追加しています:
fun MutableList<Int>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // 'this' がリストに対応する
this[index1] = this[index2]
this[index2] = tmp
}
拡張関数内のthisキーワードは、レシーバーオブジェクト(ドットの前に渡されるオブジェクト)に対応します。このような関数は、任意の MutableList に対して呼び出すことができます。
val list = mutableListOf(1, 2, 3)
list.swap(0, 2) // swap()' 内の 'this' は 'list' の値を保持します
この関数は、どのMutableListに対しても意味があり、汎用的に作ることができます。
fun <T> MutableList<T>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // 'this' はリストに対応する
this[index1] = this[index2]
this[index2] = tmp
}
解答例
fun Int.r(): RationalNumber = RationalNumber(this, 1)
fun Pair<Int, Int>.r(): RationalNumber = RationalNumber(first, second)
data class RationalNumber(val numerator: Int, val denominator: Int)