改进翻译

区间与数列

Kotlin 可通过调用 kotlin.ranges 包中的 rangeTo() 函数及其操作符形式的 .. 轻松地创建两个值的区间。 通常,rangeTo() 会辅以 in!in 函数。

if (i in 1..4) {  // 等同于 1 <= i && i <= 4
    print(i)
}

整数类型区间(IntRangeLongRangeCharRange)还有一个拓展特性:可以对其进行迭代。 这些区间也是相应整数类型的等差数列。 这种区间通常用于 for 循环中的迭代。

fun main() {
//sampleStart
    for (i in 1..4) print(i)
//sampleEnd
}

要反向迭代数字,请使用 downTo 函数而不是 ..

fun main() {
//sampleStart
    for (i in 4 downTo 1) print(i)
//sampleEnd
}

也可以通过任意步长(不一定为 1 )迭代数字。 这是通过 step 函数完成的。

fun main() {
//sampleStart
    for (i in 1..8 step 2) print(i)
    println()
    for (i in 8 downTo 1 step 2) print(i)
//sampleEnd
}

要迭代不包含其结束元素的数字区间,请使用 until 函数:

fun main() {
//sampleStart
    for (i in 1 until 10) {       // i in [1, 10), 10被排除
        print(i)
    }
//sampleEnd
}

区间

区间从数学意义上定义了一个封闭的间隔:它由两个端点值定义,这两个端点值都包含在该区间内。 区间是为可比较类型定义的:具有顺序,可以定义任意实例是否在两个给定实例之间的区间内。 区间的主要操作是 contains,通常以 in!in 操作符的形式使用。

要为类创建一个区间,请在区间起始值上调用 rangeTo() 函数,并提供结束值作为参数。 rangeTo() 通常以操作符 .. 形式调用。

class Version(val major: Int, val minor: Int): Comparable<Version> {
    override fun compareTo(other: Version): Int {
        if (this.major != other.major) {
            return this.major - other.major
        }
        return this.minor - other.minor
    }
}

fun main() {
//sampleStart
    val versionRange = Version(1, 11)..Version(1, 30)
    println(Version(0, 9) in versionRange)
    println(Version(1, 20) in versionRange)
//sampleEnd
}

数列

如上个示例所示,整数类型的区间(例如 IntLongChar)可视为等差数列。 在 Kotlin 中,这些数列由特殊类型定义:IntProgressionLongProgressionCharProgression

数列具有三个基本属性:first 元素、last 元素和一个非零的 step。 首个元素为 first,后续元素是前一个元素加上一个 step。 除非数列为空,否则最后一个元素总是被迭代命中。 以确定的步长在数列上进行迭代等效于 Java/JavaScript 中基于索引的 for 循环。

for (int i = first; i <= last; i += step) {
  // ……
}

通过迭代数列隐式创建区间时,此数列的 firstlast 元素是区间的端点,step 为 1 。

fun main() {
//sampleStart
    for (i in 1..10) print(i)
//sampleEnd
}

要指定数列步长,请在区间上使用 step 函数。

fun main() {
//sampleStart
    for (i in 1..8 step 2) print(i)
//sampleEnd
}

计算该数列的最后一个元素,以找到正步长的最大值不大于最终值,或负步长的最小值不小于最终值,使得 (last - first) % step == 0.

要创建反向迭代的数列,请在定义其区间时使用 downTo 而不是 ..

fun main() {
//sampleStart
    for (i in 4 downTo 1) print(i)
//sampleEnd
}

数列实现 Iterable<N>,其中 N 分别是 IntLongChar,因此可以在各种集合函数(如 mapfilter 与其他)中使用它们。

fun main() {
//sampleStart
    println((1..10).filter { it % 2 == 0 })
//sampleEnd
}