编程Kotlin开发者,后端开发者

Kotlin中的数值范围(Range和Progression)机制是如何工作的,如何创建自定义范围,以及它们可以用于哪些任务?

用 Hintsage AI 助手通过面试

回答。

**范围(Range)和进展(Progression)**是Kotlin中表示具有特定步长的值序列的内置机制。它们通常在循环、条件、集合遍历和数据验证时使用。Range作为这种方式之一出现,使Kotlin的语法比Java更加简洁和表达力强。

问题历史

在Java中,类似任务通过带索引的for和while循环来解决——繁琐且容易出错。在Kotlin中,出现了创建范围的紧凑操作符(例如,1..10)和设置步长的方法。

问题

  • 需要轻松传递值范围(例如,从1到100的所有数值)。
  • 增加遍历和验证的便利性。
  • 允许为自定义类型重写范围。

解决方案

Kotlin提供了标准的数值范围(IntRange, LongRange, CharRange, UIntRange等)和用于创建自定义进展的接口:

代码示例:

for (i in 1..5) print("$i ") // 1 2 3 4 5 for (i in 5 downTo 1 step 2) print("$i ") // 5 3 1 // 检查值 val x = 42 if (x in 1..100) println("在范围内!")

自定义范围

可以通过实现操作符rangeTo和Progression来为自定义类型定义范围:

data class Version(val major: Int, val minor: Int) : Comparable<Version> { override fun compareTo(other: Version) = compareValuesBy(this, other, Version::major, Version::minor) } operator fun Version.rangeTo(other: Version) = VersionRange(this, other) class VersionRange( override val start: Version, override val endInclusive: Version ) : ClosedRange<Version> for (v in Version(1, 0)..Version(1, 2)) println(v)

关键特点:

  • 创建范围的紧凑语法(start..enddownTostep)。
  • 内置的归属检查(in!in)。
  • 可以为自定义类型定义范围和进展。

难题问题。

表达式1..5实际上返回什么?

它创建了一个实现接口ClosedRange<Int>IntRange类的实例。这不是一个集合,而是一个定义边界和步长的对象。懒惰实现。

为什么Range的步长(step)总是1?如何更改步长?

默认情况下,范围的步长为1(在downTo时为-1)。要更改步长,使用方法step和downTo。例如:

for (i in 2..10 step 2) println(i)

可以使用未实现Comparable的类型的范围吗?

不可以,为了正确工作,自定义范围的类型必须实现Comparable接口,否则操作符rangeTo将无法执行。

常见错误和反模式

  • 尝试在不使用方法step的情况下更改Range的步长。
  • 使用不具备Comparable的类型的范围。
  • 方向混乱(例如,5..1不会返回任何结果)。

生活中的例子

消极案例

开发者使用循环for (i in 5..1)而不使用downTo,期望会得到"5, 4, 3, 2, 1",但实际上循环一次都不会执行。

优点:

  • 语法简单。

缺点:

  • 负范围的行为不明显。
  • 初学者容易混淆。

积极案例

使用downTo和step的进展遍历数据报告,代码紧凑且自文档化。

优点:

  • 简洁的风格。
  • 越界错误不太可能发生。

缺点:

  • 需要了解步长和方向的细节。