[毎日Kotlin] Day17. Range to

2018.02.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

毎日Kotlinシリーズです。

このシリーズを初めての方はこちらです。「毎日Kotlin」はじめました | Developers.IO

問題

Range to | Try Kotlin

Implement the function MyDate.rangeTo(). This allows you to create a range of dates using the following syntax:

MyDate(2015, 5, 11)..MyDate(2015, 5, 12)

Note that now the class DateRange implements the standard ClosedRange interface and inherits contains method implementation.

operator fun MyDate.rangeTo(other: MyDate) = TODO()

class DateRange(override val start: MyDate, override val endInclusive: MyDate): ClosedRange<MyDate>

fun checkInRange(date: MyDate, first: MyDate, last: MyDate): Boolean {
    return date in first..last
}

//Day15で実装していたMyDate
data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) : Comparable<MyDate> {
    override fun compareTo(other: MyDate) = when {
        year != other.year -> year - other.year
        month != other.month -> month - other.month
        else -> dayOfMonth - other.dayOfMonth
    }
}

狙い

ここで考えて欲しい問題の意図はなんだろうか? [毎日Kotlin] Day15. Comparison(演算子)[毎日Kotlin] Day16. In range からの続きです。

date in first..lastの記法でcontainsを呼ぶには、ClosedRange閉鎖区間のインターフェイスを実装していると簡単にできます。ClosedRangeはClosedRange<T: Comparable>なので、Comparableが実装してあることが条件になっています。

つまり、、、、続きは考えてみましょう。

解答例

operator fun MyDate.rangeTo(other: MyDate) = DateRange(this, other)

[毎日Kotlin] Day15. Comparison(演算子)[毎日Kotlin] Day16. In range からの続きでMyDateはすでにComparable実装済みです。

DateRangeでClosedRangeが実装されているので、MyDate.rangeToでは、DateRangeを作る拡張を作ればよいだけですね。

operatorが複数のoperatorで作られていて、一つ一つのoperatorは単純な実装ですね。かっこよく演算子で処理したくなってきました。operatorを使いこせると美しい記述にできそうです。しかし初見殺しかもしれない。バランスが大事です!

あとがき

Day18.でまたお会いしましょう。