Question
In Go, range can iterate over slices, arrays, maps, strings, and channels. Is there a built-in way to iterate directly over a numeric range, similar to this?
for i := range [1..10] {
fmt.Println(i)
}
Also, does Go have a built-in representation for integer ranges similar to Ruby's Range class, or is there another idiomatic way to work with a sequence of numbers?
Short Answer
By the end of this page, you will understand how Go handles numeric iteration, why range does not work like Ruby ranges, and the idiomatic way to loop through integers using Go's for statement. You will also learn how to build your own integer range values when needed.
Concept
Go does not have a built-in integer range type like Ruby's Range, and range in Go does not mean “generate numbers from start to end.”
In Go, range is used to iterate over existing collections or stream-like values, such as:
- arrays
- slices
- maps
- strings
- channels
That means range works over data that already exists. It does not create a sequence of integers for you.
If you want to count from 1 to 10 in Go, the idiomatic solution is a regular for loop:
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
This matters because Go is intentionally simple. Instead of adding a special numeric range syntax, the language relies on one flexible looping construct: for.
So the key idea is:
- Use
rangeto iterate over an existing collection. - Use
forwith start, condition, and increment to iterate through numbers.
If you really need a reusable range-like value, you can create a slice of integers yourself or define your own helper function.
Mental Model
Think of Go's range like walking through items that are already placed in a row on a table.
- A slice: a row of values already exists.
- A map: a set of key-value pairs already exists.
- A string: a sequence of characters already exists.
But a numeric interval like 1..10 is not a row of stored values in Go. It is only an idea: “start here and count until there.”
For that, Go expects you to use a for loop, which is like saying:
- Start at
1 - Keep going while
i <= 10 - Add
1each time
So range walks over something that exists, while for can generate a counting process.
Syntax and Examples
Basic numeric loop
The standard way to iterate over integers in Go is:
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
This means:
- initialize
ito1 - continue while
i <= 10 - increment
iafter each iteration
Starting from zero
for i := 0; i < 5; i++ {
fmt.Println(i)
}
Output:
0
1
2
3
4
Using range with a slice instead
If you create a slice first, then you can use range:
numbers := []int{1, 2, 3, 4, 5}
for index, value := numbers {
fmt.Println(index, value)
}
Step by Step Execution
Consider this code:
for i := 3; i <= 5; i++ {
fmt.Println(i)
}
Step by step:
-
i := 3- Go creates
iand sets it to3.
- Go creates
-
i <= 53 <= 5is true, so the loop body runs.fmt.Println(i)prints3.
-
i++ibecomes4.
-
i <= 54 <= 5is true.- Print
4.
-
i++
Real World Use Cases
Numeric iteration appears everywhere in Go programs.
Repeating work a fixed number of times
for i := 0; i < 3; i++ {
fmt.Println("Retrying...")
}
Useful for retry attempts, polling, or repeated tasks.
Processing indexes in a slice
items := []string{"a", "b", "c"}
for i := 0; i < len(items); i++ {
fmt.Println(i, items[i])
}
Helpful when you need index-based access.
Generating test data
for i := 1; i <= 100; i++ {
fmt.Println("user", i)
}
Common in scripts, fixtures, and sample data generation.
Pagination and batching
for page := 1; page <= totalPages; page++ {
fmt.Println("Fetching page", page)
}
Useful in APIs and background jobs.
Time-based counters or simulations
Real Codebase Usage
In real Go codebases, developers usually prefer the simplest tool that matches the job.
Simple counting with for
For numeric loops, a standard for loop is the default choice:
for i := 0; i < maxRetries; i++ {
err := tryOperation()
if err == nil {
break
}
}
Guarding loop boundaries carefully
Developers often use constants or variables to avoid magic numbers:
const maxWorkers = 5
for i := 0; i < maxWorkers; i++ {
startWorker(i)
}
Index loops when values must be updated
scores := []int{10, 20, 30}
for i := 0; i < len(scores); i++ {
scores[i] += 5
}
This is common when you need to modify elements in place.
range when iterating existing data
Common Mistakes
Mistake 1: Expecting range to generate numbers
Broken idea:
for i := range [1..10] {
fmt.Println(i)
}
Why it is wrong:
- Go has no
1..10syntax. rangedoes not generate integer sequences.
Use this instead:
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
Mistake 2: Off-by-one errors
Broken code:
for i := 1; i < 10; i++ {
fmt.Println(i)
}
This prints 1 through 9, not 10.
Correct version:
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
Comparisons
| Concept | What it does | Best use case |
|---|---|---|
for i := 1; i <= 10; i++ | Counts through integers | Numeric iteration |
for _, v := range slice | Iterates over existing slice values | Processing collections |
for k, v := range map | Iterates over map entries | Reading maps |
for condition {} | Repeats while condition stays true | Unknown number of iterations |
for vs range
| Feature | for |
|---|
Cheat Sheet
Numeric loop
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
Count from zero
for i := 0; i < n; i++ {
// use i
}
Loop backwards
for i := 10; i >= 1; i-- {
fmt.Println(i)
}
Custom step size
for i := 0; i <= 10; i += 2 {
fmt.Println(i)
}
range over slice
nums := []int{10, 20, 30}
for index, value := range nums {
fmt.Println(index, value)
}
Important rules
- Go has no built-in
1..10syntax. - Go has no built-in integer range type.
FAQ
Why doesn't Go support 1..10 syntax?
Go keeps the language small and explicit. Numeric iteration is handled with for instead of special range syntax.
Can I use range to count from 1 to 10 in Go?
Not directly. range iterates over existing values such as slices, maps, strings, and channels.
Does Go have a built-in Range type like Ruby?
No. If you need a reusable range-like structure, you must build it yourself.
What is the idiomatic way to loop over numbers in Go?
Use a standard for loop:
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
When should I use range instead of for?
Use range when you already have a collection, such as a slice or map, and want to iterate through its elements.
How do I include the end number in a Go loop?
Use <= instead of <.
Mini Project
Description
Build a small Go program that prints a sequence of integers between two values. This demonstrates the idiomatic way to work with numeric ranges in Go without relying on a built-in Range type.
Goal
Create a reusable function that prints or returns integers from a start value to an end value using standard Go loops.
Requirements
- Write a function that accepts
startandendintegers. - Return a slice containing all integers from
starttoend, inclusive. - Use a
forloop to build the result. - In
main, call the function and print each number. - Handle the case where
startis greater thanendby returning an empty slice.
Keep learning
Related questions
Blank Identifier Imports in Go: What `_` Means in an Import Statement
Learn what `_` means in a Go import, why blank identifier imports run package init code, and when to use them safely.
Check if a Value Exists in a Slice in Go
Learn how to check whether a value exists in a slice in Go, and why Go has no Python-style `in` operator for arrays or slices.
Concatenating Slices in Go with append
Learn how to concatenate two slices in Go using append and the ... operator, with examples, pitfalls, and practical usage.