Golang reverse range and iterate a slice backwards

Golang reverse range and golang range reverse with a backward index loop; golang range backwards using forward range and remapped index; golang iterate over slice and golang iterate slice backwards; golang reverse slice with slices.Reverse; go reverse range and go reverse slice patterns.

Published

Updated

Read time 3 min read

Reviewed byDeepak Prasad

Golang reverse range and iterate a slice backwards

The Go range keyword always walks a slice from low index to high index, so searches like golang reverse range, golang range reverse, go reverse range, golang range backwards, and reverse range golang really mean “choose an index strategy,” not a different range syntax. This page shows backward for loops, a forward range with a remapped index (still golang iterate slice backwards), mutating slices.Reverse for golang reverse slice / go reverse slice / reverse slice golang, a small generic helper, and an optional channel iterator. For ordinary forward passes, see iterate over a slice patterns (arrays and slices share the same loop forms).

Tested with Go 1.24 on Linux.


Classic reverse index loop

Count from len(s)-1 down to 0:

go
package main

import "fmt"

func main() {
	intSlice := []int{12, 23, 9, 32, 182}
	for i := len(intSlice) - 1; i >= 0; i-- {
		fmt.Println(intSlice[i])
	}
}
Output

Running it prints 182, 32, 9, 23, then 12 on separate lines.


Forward range with a remapped index

Here range still moves i from 0 upward, but you read s[len(s)-1-i] so values appear in reverse order. That is a common answer to golang range reverse when you want to keep a range header:

go
package main

import "fmt"

func main() {
	intSlice := []int{12, 23, 9, 32, 182}
	n := len(intSlice)
	for i := range intSlice {
		fmt.Println(intSlice[n-1-i])
	}
}
Output

The printed sequence matches the first example.


slices.Reverse: reverse slice data, then range

Go 1.21 adds slices.Reverse, which reverses elements in place. If callers must keep the original order, clone first with slices.Clone:

go
package main

import (
	"fmt"
	"slices"
)

func main() {
	orig := []int{12, 23, 9, 32, 182}
	rev := slices.Clone(orig)
	slices.Reverse(rev)
	for _, v := range rev {
		fmt.Println(v)
	}
	fmt.Println("orig unchanged:", orig)
}
Output

The loop over rev prints the same reverse order; orig stays [12 23 9 32 182].


Generic reverseIterate

A type parameter lets one helper print many slice types in reverse (see generics in Go):

go
package main

import "fmt"

func reverseIterate[T any](slice []T) {
	for i := len(slice) - 1; i >= 0; i-- {
		fmt.Printf("%v ", slice[i])
	}
}

func main() {
	reverseIterate([]int{12, 23, 9, 32, 182})
	fmt.Println()
	reverseIterate([]string{"This", "is", "reverse", "iterating", "example"})
	fmt.Println()
}
Output

Sample output begins with 182 32 9 23 12 on the first line and the words of the string slice reversed on the second.


Optional: channel as a reverse iterator

You can stream elements in reverse order from a goroutine without reversing the backing array. This is rarely needed for simple printing but shows how channels can wrap a walk order:

go
package main

import "fmt"

func reverseStrings(slice []string) <-chan string {
	ch := make(chan string)
	go func() {
		for i := range slice {
			ch <- slice[len(slice)-1-i]
		}
		close(ch)
	}()
	return ch
}

func main() {
	s := []string{"a", "b", "c", "d"}
	for v := range reverseStrings(s) {
		fmt.Println(v)
	}
	fmt.Println("original:", s)
}
Output

The channel yields d through a; s is still [a b c d].


Summary

Golang reverse range is not a special range form: use a decreasing index, remap inside range, call slices.Reverse (optionally on a slices.Clone) and then range forward, or factor a small generic reverseIterate. That covers golang iterate over slice in reverse as well as golang reverse slice when you really want data reversed versus only visiting indices backwards. Prefer the index loop or slices.Reverse for clarity; reach for channels when a pipeline already fits your design.


References


Frequently Asked Questions

1. Is there a golang reverse range keyword?

No. The range clause always walks from the start of the slice toward the end. Reverse iteration uses a classic for loop with a decreasing index, or a forward range where you map the index to len-1-i, or you reverse the slice data then range forward.

2. How do I golang iterate slice backwards without changing the original slice?

Use a backward index loop over the original, or clone with slices.Clone then slices.Reverse on the copy before ranging, or only print using remapped indices so the underlying slice order stays the same.

3. What is the idiomatic golang reverse slice for printing?

Since Go 1.21, slices.Reverse mutates a slice in place; combine with slices.Clone if you must preserve order. For hot paths that only need elements in reverse, a simple for i := len(s)-1; i >= 0; i-- loop avoids an extra copy.

4. How does this relate to golang iterate over slice normally?

Forward iteration is for i, v := range s. Reverse is the same data with a different index order; see iterating arrays and slices basics in the linked forward-iteration article.
Tuan Nguyen

Data Scientist

Proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise …