kotlin 之 range學習

1.原理實現(xiàn)

這里涉及兩個操作符重載,代表范圍(range)的 .. 和代表包含(contain)的 in,他們常常一起出現(xiàn)

range的功能需要類擴展rangeTo來實現(xiàn),操作符號是兩個點-> ..

rangeTo返回類型是interface ClosedRange<T: Comparable<T>>,它實現(xiàn)了contains方法

contain的功能需要類擴展contains來實現(xiàn),操作符號是 in 或是 !in

2.常見使用方式

上升范圍

i in 1..4

下降范圍

i in 4 downTo 1

進階范圍

i in 1..10 step 3

i in 1 downTo 10 step 3

->但是注意進階的范圍不會超過結尾的最大值和最小值

開區(qū)間范圍

i in 1 until 10

這里10是不包含的

3.kotlin整型的range

是一個Progression實例,例如IntProgression, LongProgression, and CharProgression

Progression實現(xiàn)了Iterable<T>接口,因此這個范圍是可以支持集合函數(shù)的,比如map,filter之類

(1..10).filter{it%2 == 0}

for (i in 1..10) print (i)

4.自定義類支持range

其實很簡單,只要實現(xiàn)Comparable接口,然后rangeTo返回一個CloseRange<T>就ok了

不過需要了解的是,這個僅僅能讓我們的代碼支持比較功能

由于我沒有支持Iterator所以類似

for (newdate in dateStart..dateEnd)

是無法支持的

而downTo以及step也是無法支持的因為沒有實現(xiàn)對應的擴展函數(shù),而這兩者在Int的實現(xiàn)方式都是通過IntProgression來實現(xiàn)的,這兩者都需要實現(xiàn)迭代器才可以支持

來看看他倆的實現(xiàn)就整明白了

public infix fun Int.downTo(to: Byte): IntProgression {

    return IntProgression.fromClosedRange(this, to.toInt(), -1)

}

public infix fun IntProgression.step(step: Int): IntProgression {

    checkStepIsPositive(step > 0, step)

    return IntProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)

}

downTo是Int的擴展函數(shù),而step是IntProgression的擴展函數(shù),這么一來才能這樣瀟灑的寫

for(x in 10 downTo 2 step 2)

downTo看起來好像正好和range符號..正好相反,但實際上實現(xiàn)卻大不同,downTo會直接返回一個Iterator<T>調用的是迭代器一個個比較,但是“..”只會調用一下比較方法compareTo就OK了,實現(xiàn)效率完全不同

Kotlin確實寫起來很瀟灑,但是背后的調用關系還是得整明白,得知其所以然

5.附我的自定義range代碼

class MyDate(val year:Int, val month:Int, val day:Int):Comparable<MyDate>{
    override fun compareTo(other: MyDate): Int {
        return when {
            year != other.year -> year - other.year
            month != other.month -> month - other.month
            day != other.day -> day - other.day
            else -> 0
        }
    }

    operator fun rangeTo(other: MyDate):MyDateRange {
        return MyDateRange(this, other)
    }
}

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

fun testRange() {
    val date2020_3_25 = MyDate(2020, 3, 25)
    val date2020_3_20 = MyDate(2020, 3, 20)
    val date2020_3_22 = MyDate(2020, 3, 22)
    val date2020_4_12 = MyDate(2020, 4, 12)
    val r1 = date2020_3_22 in date2020_3_20..date2020_3_25
    val r2 = date2020_3_22 < date2020_3_25
    val r3 = date2020_4_12 in date2020_3_20..date2020_3_25
    Log.i("lily", "date2020_3_22 in date2020_3_20..date2020_3_25 = $r1")
    Log.i("lily", "date2020_3_22 < date2020_3_25 = $r2")
    Log.i("lily", "date2020_4_12 in date2020_3_20..date2020_3_25 = $r3")
//    for (xdate in date2020_3_20..date2020_3_25){//不支持,因為沒有實現(xiàn)Iterator
//
//    }
//    for (i in date2020_3_25 downTo date2020_3_22){//不支持,因為沒有實現(xiàn)downTo擴展函數(shù)
//
//    }
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容