skip to content

Range & in Operators

The .. and ..< operators build ranges, and x in range is a membership check that desugars to contains(). The same in operator drives for-loop iteration, which is why understanding one explains the other.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

questions

5

What does the .. operator do in Kotlin, and how do you check whether a value falls inside the resulting range?

level: juniorimportance: must knowfreq 70%

answer

  1. 1..10 = rangeTo, inclusive both ends
  2. in -> contains; !in -> !contains
  3. ..< -> rangeUntil, excludes upper
  4. in also means iterate in for loops
  5. Range is a real object you can store

basics

~10 s

The .. operator builds a range, like 1..10 meaning 1 through 10 inclusive. You check if something is inside it with the in keyword, for example x in 1..10.

solid answer

~40 s

The .. operator (compiled to rangeTo) builds a range. For Ints, 1..10 creates an IntRange covering 1 through 10 inclusive on both ends. Membership is tested with x in range, which the compiler desugars to range.contains(x), and x !in range for the negation. The same in keyword also drives iteration: for (i in 1..10) loops over every value. Ranges are first-class objects you can store in a variable (val r = 1..10), pass around, and query (r.first, r.last, r.contains(5)). Because IntRange is also an Iterable, you can call collection-style functions on it. The closed range 1..10 includes 10; if you need to stop before the end you use ..< instead.

code

kotlin · 5 lines
kotlin
val r = 1..10
println(5 in r)     // true
println(10 in r)    // true (inclusive)
println(11 !in r)   // true
for (i in 1..3) print(i)  // 123

go deeper

for a junior

Knows 1..10 is inclusive and uses x in range to test membership.

for a middle

Explains the rangeTo/contains desugaring and the difference between .. and ..<.

for a senior

Notes in works on any contains-defining type and distinguishes iteration-in from membership-in.

for a principal

Frames ranges as a convention-based operator design enabling extensible, allocation-light boundary checks across types.

## What .. does The `..` operator is Kotlin's **range** operator. Writing `1..10` produces a `IntRange` object representing every integer from 1 to 10 **inclusive of both endpoints**. `..` is syntactic sugar: `1..10` compiles to `1.rangeTo(10)`. `rangeTo` is an operator function defined on the comparable primitive types (`Int`, `Long`, `Char`, etc.). ## The `in` operator for membership To ask "is this value inside the range?" you use the `in` keyword: ```kotlin val r = 1..10 println(5 in r) // true -> desugars to r.contains(5) println(11 in r) // false println(11 !in r) // true -> desugars to !r.contains(11) ``` `x in range` is **desugared by the compiler** into `range.contains(x)`, and `x !in range` into `!range.contains(x)`. So `in`/`!in` are not magic for ranges specifically — they work on anything that defines a `contains` operator function (lists, sets, strings, your own types). ## Ranges are objects A range is a normal value. You can store it, return it, and query it: ```kotlin val valid = 0..100 val ok = score in valid println(valid.first) // 0 println(valid.last) // 100 ``` ## `in` also drives `for` loops The same `in` keyword iterates: ```kotlin for (i in 1..5) print(i) // 12345 ``` `IntRange` implements `Iterable<Int>`, so a `for (x in range)` loop walks each element. (Note: the `in` in a `for` header is iteration, while `in` in a boolean position is the `contains` membership check — same keyword, two roles.) ## Inclusive vs half-open `1..10` is **closed/inclusive** — it includes 10. Kotlin also has `..<` (the `rangeUntil` operator) for a **half-open** range that excludes the upper bound: `1..<10` covers 1 through 9. Prefer `..<` over the older `until` infix function for index loops to avoid off-by-one bugs. ## Key APIs/keywords - `..` -> `rangeTo` - `..<` -> `rangeUntil` - `in` -> `contains` - `!in` -> `!contains` - `IntRange`, `.first`, `.last`, `Iterable`

  • Does 1..10 include 10?
    Yes. `..` builds a closed (inclusive) range, so both 1 and 10 are members. Use `1..<10` if you need to exclude the upper bound.
  • What is x in range actually compiled to?
    `range.contains(x)`. The `in` operator is sugar for a call to the `contains` operator function.

A range is like a guest list: in asks 'is this name on the list?', and a for loop reads every name off it.

saying these in an interview costs you the question

  • Thinking 1..10 excludes 10 (it is inclusive)
  • Believing in only works on ranges, not on lists/strings
  • Not knowing in desugars to contains()
  • Confusing the for-loop in with membership in

context

open as a page

What is the difference between .. and ..< in Kotlin, and which operator functions do they map to?

level: middleimportance: must knowfreq 60%

basics

~10 s

1..10 includes both ends (1 through 10). 1..<10 excludes the top end (1 through 9). The first uses rangeTo, the second uses rangeUntil.

open as a page

How does the compiler translate x in range and x !in range, and why does that let you use in on non-range types?

level: middleimportance: should knowfreq 50%

basics

~10 s

x in y becomes y.contains(x), and x !in y becomes !y.contains(x). Any type that defines a contains function works with in, not just ranges — lists, sets, and strings do too.

open as a page

How does in drive for-loop iteration over ranges, and how do you iterate descending or with a step?

level: seniorimportance: should knowfreq 45%

basics

~10 s

for (i in 1..5) loops 1 to 5 because the range can be iterated. To go down use downTo (5 downTo 1), and to skip values use step (1..10 step 2).

open as a page

How can you build a range over a custom Comparable type, and what does ClosedRange give you that an iterable progression does not?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

If your type implements Comparable, you get .. for free via the rangeTo extension. That builds a closed range you can test with in, but you cannot loop over it unless you also define how to step through values.

open as a page