skip to content

How do you create a range of integers in Kotlin, and what does the `..` operator produce?

level: juniorimportance: must knowfreq 78%

answer

  1. `a..b` == `a.rangeTo(b)`
  2. Inclusive on BOTH ends
  3. IntRange is an IntProgression -> iterable
  4. start > end => empty, not descending
  5. Double `..` works with `in` but not `for`

basics

~10 s

Write 1..5 to make a range from 1 to 5 including both ends. You can then loop over it with for (i in 1..5).

solid answer

~30 s

The `..` operator builds a closed (inclusive) range. `1..5` desugars to `1.rangeTo(5)` and returns an `IntRange` covering 1, 2, 3, 4, 5 — both endpoints are included. It's a `ClosedRange` and also an `IntProgression`, so it is iterable: `for (i in 1..5) { ... }` works directly. You can also test membership with `in`: `3 in 1..5` is `true`. `..` is an operator function defined via `operator fun rangeTo`, available on `Int`, `Long`, `Char`, and other `Comparable` types. For non-iterable comparables (like `Double` or `String`) `..` still creates a `ClosedRange` usable with `in`, but you cannot iterate it.

code

kotlin · 5 lines
kotlin
val r: IntRange = 1..5
println(r.toList())   // [1, 2, 3, 4, 5]
println(r.first)       // 1
println(r.last)        // 5
println((5..1).isEmpty()) // true (does NOT count down)

go deeper

for a junior

Knows 1..5 is inclusive both ends and loops with for (i in 1..5).

for a middle

Explains .. desugars to rangeTo, returns IntRange (a progression), and that 5..1 is empty not descending.

for a senior

Distinguishes ClosedRange vs IntProgression, knows Double ranges are non-iterable, and the in membership semantics.

for a principal

Frames .. as an overloadable operator (operator fun rangeTo) usable on custom Comparable types, and reasons about the range/progression type hierarchy.

## The `..` operator In Kotlin, `a..b` is the **range** operator. It is shorthand for the operator function call `a.rangeTo(b)`. For integers it produces an **`IntRange`** — an inclusive (closed) interval that contains every value from `a` to `b`, **both endpoints included**. ```kotlin val r = 1..5 // IntRange: 1, 2, 3, 4, 5 val same = 1.rangeTo(5) // identical — .. is sugar for rangeTo ``` ## What you get back - `1..5` is an `IntRange`, which is a subtype of `IntProgression` (an arithmetic sequence with a step, default `1`) and of `ClosedRange<Int>`. - Because it is a progression, it is **iterable** — you can use it in a `for` loop. - Because it is a `ClosedRange`, you can use the **`in`** operator for membership tests. ```kotlin for (i in 1..5) print(i) // 12345 println(3 in 1..5) // true println(6 in 1..5) // false ``` ## Endpoints and empty ranges `..` is **inclusive on both ends**. If the start is greater than the end, the range is **empty** (it iterates zero times) — `5..1` produces nothing in a `for` loop and `isEmpty()` returns `true`. It does *not* throw and does *not* count down; to count down you need `downTo`. ## Types it works on `rangeTo` is defined for `Int`, `Long`, `Char`, and any `Comparable`. For `Char`, `'a'..'f'` is a `CharRange`. For non-integral comparables like `Double` or `String`, `..` makes a `ClosedRange` you can test with `in` but **cannot iterate**, because there is no natural integer step. ```kotlin println(0.5 in 0.0..1.0) // true — works // for (x in 0.0..1.0) ... // does NOT compile: not iterable ``` ## Related operators (same family) - `..<` / `until` — half-open (excludes the end). - `downTo` — descending range. - `step` — change the increment.

  • Is `1..5` inclusive or exclusive of 5?
    Inclusive — it contains 5. Use `1..<5` or `1 until 5` to exclude it.
  • What happens with `5..1` in a for loop?
    Nothing iterates — it's an empty range. Use `5 downTo 1` to descend.
  • Can you iterate `0.0..1.0`?
    No. Double ranges support `in` membership but are not progressions, so they are not iterable.

Like a guest list from seat 1 to seat 5 — both the first and last seats are on the list.

saying these in an interview costs you the question

  • Thinking `..` excludes the upper bound
  • Believing `5..1` counts down
  • Claiming you can `for`-loop over a `Double` range
  • Saying `..` returns a `List` rather than a lazy range/progression

context