Как сделать Котлин сравнимым типом?

просто учимся определять тип DateRange

val wholeYear2017 = Date(2017,1,1)..Date(2017,12,31)

Итак, я создал тип, как показано ниже

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

class Date (val year: Int, val month: Int, val day: Int) {

    operator fun compareTo(other: Date): Int {
        if (this.year > other.year) return 1
        if (this.year < other.year) return -1
        if (this.month > other.month) return 1
        if (this.month < other.month) return -1
        if (this.day > other.day) return 1
        if (this.day < other.day) return -1
        return 0
    }

    operator fun rangeTo(that: Date): DateRange = DateRange(this, that)
}

но я получил ошибку при компиляции

One type of argument expected for class DateRange<Date: Comparable<Date>> : ClosedRange<Date>

что я пропустил? Правильно ли я это сделал?

3 ответов


ваш вопрос действительно о том, как создать сопоставимый тип? Тогда просто ваш тип реализует сопоставимый интерфейс (override compareTo).

class Date(val year: Int, val month: Int, val day: Int) : Comparable<Date> {
    override operator fun compareTo(other: Date): Int {
        if (this.year > other.year) return 1
        if (this.year < other.year) return -1
        if (this.month > other.month) return 1
        if (this.month < other.month) return -1
        if (this.day > other.day) return 1
        if (this.day < other.day) return -1
        return 0
    }
 }

вам не нужен rangeTo метод, потому что все Comparable<T> типы есть


вы почти там:

во-первых, вы должны сделать свой класс Comparable:

class Date (val year: Int, val month: Int, val day: Int): Comparable<Date> {

во-вторых, вы должны указать общий тип возвращаемого типа или просто опустить его (пусть компилятор выведет его)

operator fun rangeTo(that: Date): DateRange<Date> = DateRange(this, that)
operator fun rangeTo(that: Date) = DateRange(this, that)

нужно реализовать Comparable интерфейс. Вы можете использовать compareValuesBy вспомогательную функцию:

data class Data(
        val a: Int,
        val b: Int
) : Comparable<Data> {
    override fun compareTo(other: Data) = compareValuesBy(this, other,
            { it.a },
            { it.b }
    )
}