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ù)
//
// }
}