Kotlin学习笔记5-3 其他-区间

本文介绍Kotlin中区间表达式的基本用法,包括区间创建、遍历、倒序及步进控制等特性。详细解释了Kotlin如何利用rangeTo、in、!in等操作符实现区间判断,以及如何通过downTo、step和until进行特定范围的遍历。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

区间

Kotlin官网:Other-Ranges
区间表达式通过运算符..的函数rangeTo实现,in!in表示区间内/不在区间内。
comparable可比较类型都可以获取区间,Kotlin针对基本类型做了优化:

if (i in 1..10) { // equivalent of 1 <= i && i <= 10
    println(i)
}

整型的区间(IntRange, LongRange, CharRange)可以用来遍历,编译器会转换成基于下标的for循环:

for (i in 1..4) print(i) // prints "1234"

for (i in 4..1) print(i) // prints nothing

如果要倒序遍历,使用downTo函数:

for (i in 4 downTo 1) print(i) // prints "4321"

如果步进不是默认的1,使用step函数自定义步进:

for (i in 1..4 step 2) print(i) // prints "13"

for (i in 4 downTo 1 step 2) print(i) // prints "42"

如果不想包含右边界(左闭右开)使用until函数:

for (i in 1 until 10) { // i in [1, 10), 10 is excluded
     println(i)
}

原理

区间由基础接口ClosedRange<T>实现,定义了一个封闭区间,包含起点和终点(含终点)。
遍历通过级数progression实现,有IntProgression, LongProgression, CharProgression等等实现类。
progression是Iterable<N>的子类,N可以是Int, Long或Char,可以用来for循环。progression遍历等价于Java中的for循环:

for (int i = first; i != last; i += step) {
  // ...
}

整型类型的..运算符会创建一个同时实现了ClosedRange<T>xxxProgression的实例。例如,IntRange实现了CloseRange<Int>并继承IntProgression,IntRange包含IntProgrossion的所有功能。downTo函和step函数的返回值也是xxxProgression。
progression是由xxxProgression的伴生对象的fromClosedRange函数创建的:

IntProgression.fromClosedRange(start, end, step)

last是用来确定循环终点,根据传入的起点、终点和步进计算出来,表示递增不能超过的最大值或者递减不能小于的最小值,并保证(last - first) % step == 0

工具函数

rangeTo()

整型的rangeTo直接调用的xxxRange类的构造函数:

class Int {
    //...
    operator fun rangeTo(other: Long): LongRange = LongRange(this, other)
    //...
    operator fun rangeTo(other: Int): IntRange = IntRange(this, other)
    //...
}

浮点型没有自己实现rangeTo,使用的Comparable的实现:

public operator fun <T: Comparable<T>> T.rangeTo(that: T): ClosedRange<T>

Comparable的返回值不能用来遍历。

downTo()

所有整型都有的扩展函数:

fun Long.downTo(other: Int): LongProgression {
    return LongProgression.fromClosedRange(this, other.toLong(), -1L)
}

fun Byte.downTo(other: Int): IntProgression {
    return IntProgression.fromClosedRange(this.toInt(), other, -1)
}

reversed()

xxxProgression类的扩展函数,返回一个倒序级数:

fun IntProgression.reversed(): IntProgression {
    return IntProgression.fromClosedRange(last, first, -step)
}

step()

xxxProgression类的扩展函数,返回自定义步进的级数。
步进必须是正的,所以不能用负步进实现反向遍历:

fun IntProgression.step(step: Int): IntProgression {
    if (step <= 0) throw IllegalArgumentException("Step must be positive, was: $step")
    return IntProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)
}

fun CharProgression.step(step: Int): CharProgression {
    if (step <= 0) throw IllegalArgumentException("Step must be positive, was: $step")
    return CharProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)
}

由于要保持(last - first) % step == 0,所以不同步进对应的last的值会不同,例如:

(1..12 step 2).last == 11  // progression with values [1, 3, 5, 7, 9, 11]
(1..12 step 3).last == 10  // progression with values [1, 4, 7, 10]
(1..12 step 4).last == 9   // progression with values [1, 5, 9]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值