您的位置:首页 > 其它

Kotlin基础语法 之 区间

2017-12-05 00:00 316 查看
摘要: 基础语法 之 区间

一、区间(ranges)

1.1 基本形式( rangeTo 函数)

区间表达式由具有操作符形式
..
rangeTo 函数
辅以
in
!in
形成。

区间是为任何可比较类型定义的,但对于整型原生类型,它有一个优化的实现。
以下是使用区间的一些示例:

var i = 5
if (i in 1..10) {  // 等同于 1 <= i && i <= 10 闭区间 [1,10]
println(i)
}

整型区间(IntRange、 LongRange、 CharRange)有一个额外的特性:它们可以迭代。 编译器负责将其转换为类似 Java 的基于索引的 for-循环 而无额外开销:

for (i in 1..4) print(i) // 输出“1234”

for (i in 4..1) print(i) // 什么都不输出

遍历区间:

var range = 1..10

for (value in range) {
println("value = $value")
}

for ((index, value) in range.withIndex()) {
println("index = $index  value = $value")
}

range.forEach {
println("value = $it")
}

range.forEachIndexed { index, i ->
println("index = $index  value = $i")
}

打印结果:



浮点数未定义它们的 rangeTo操作符,而使用标准库提供的泛型 Comparable 类型的操作符:

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

该区间是不能用于迭代的:

var i2 = 1.0f
if (i2 in 1.0f..12.0f){
println(i2)
}

1.2 until() --- 左边右开区间

创建一个不包含last 元素的区间,使用until:

var range = 1 until 10  //  [1,10)

例子:

for (i in 1 until 10) {   // i in [1, 10) 排除了 10
println(i)
}

打印结果:



1.3 downTo() --- 反向区间

扩展函数 downTo() 是为任何整型类型 定义的。

倒序迭代数字。

例子:

val range1 = 10 downTo 1  // 定义反向区间

1.4 reversed() --- 区间的反转

扩展函数 reversed() 是为每个 *Progression 类定义的,并且所有这些函数返回反转后的数列。

val  range = 1..10 //正向区间
val range2 = range.reversed() // 区间的反转

1.5 step() --- 步长

扩展函数 step() 是为每个 *Progression 类定义的, 所有这些函数都返回带有修改了 step 值(函数参数)的数列。

步长(step)值必须为正数,因此该函数不会更改迭代的方向:

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 值可能与原始数列的 last 值不同,以便保持不变式 (last - first) % step == 0 成立。
3ff8


例子:

for (i in 12 downTo 1 step 2) {
println(i)
}

打印结果:



var range = 1..12 step 2

二、区间是如何工作的

2.1 区间实现了该库中的一个公共接口:
ClosedRange<T>

ClosedRange<T>
在数学意义上表示一个闭区间,它是为可比较类型定义的。
它有两个端点:
start
endInclusive
他们都包含在区间内。

其主要操作是
contains
,通常以
in/!in 操作符
形式使用。

2.2 等差数列

整型数列(IntProgression、 LongProgression、 CharProgression)来表示等差数列。

数列由 first 元素、last 元素和非零的 step 定义。

第一个元素是 first,后续元素是前一个元素加上 step。

last 元素总会被迭代命中,除非该数列是空的。

数列是
Iterable<N>
的子类型,其中
N
分别为
Int、 Long 或者 Char
,所以它可用于
for-loop
, 以及像
map、filter
等函数中。

对 Progression 迭代相当于 Java/JavaScript 的基于索引的 for-loop:

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

对于整型类型,
.. 操作符
创建一个同时实现
ClosedRange<T>
*Progression
的对象。

例如,
IntRange
实现了
ClosedRange<Int>
并扩展自
IntProgression
,因此为
IntProgression
定义的所有操作也可用于
IntRange
downTo()
step()
函数的结果总是一个
*Progression


数列由在其伴生对象中定义的 fromClosedRange 函数构造:

IntProgression.fromClosedRange(start, end, step)

数列的 last 元素这样计算:对于正的 step 找到不大于 end 值的最大值、或者对于负的 step 找到不小于 end 值的最小值,使得 (last - first) % step == 0。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Kotlin区间