sort
Before You Start
- Applies to: Go 1.21+ (examples verified with Go 1.22) · Prerequisites: Base: Slices · Read time: about 10 min
TIP
If you are a developer using version 1.21 or above, I recommend using the slices standard library for sorting. It supports generics and has a more reasonably designed API.
The sort package in Go provides officially implemented sorting methods, most of which can be used out of the box. If you want to sort structs, you must implement three methods under sort.Interface: Len(), Swap(), and Less(). Since the official has already implemented three types for us: Float64Slice, StringSlice, and IntSlice, we can use these three types directly without implementing them ourselves.
type Interface interface {
// Length method
Len() int
// Comparison method
Less(i, j int) bool
// Swap method
Swap(i, j int)
}Integer Sorting
func main() {
ints := []int{1, 2, 3, 111, 5, 99, 23, 5, 66}
sort.Ints(ints)
}Floating Point Sorting
func main() {
floats := []float64{1.0, 2.5, 3.8, 1.11, 5.5, 99.99999, 23.9999, 5.66, 66}
sort.Float64s(floats)
fmt.Println(floats)
}String Sorting
func main() {
strings := []string{"helloworld", "aaa", "bbb", "ccc"}
sort.Strings(strings)
}Reverse Sorting
You need to wrap with sort.Reverse before sorting:
func main() {
floats := []float64{1.0, 2.5, 3.8, 1.11, 5.5, 99.99999, 23.9999, 5.66, 66}
sort.Sort(sort.Reverse(sort.Float64Slice(floats)))
fmt.Println(floats)
}Custom Sorting
If you want to customize struct sorting, you must implement three methods.
type Person struct {
UserId string
Username string
Age int
Address string
}
type PersonSlice []Person
// Return the length of the slice
func (p PersonSlice) Len() int {
return len(p)
}
// Comparison method
func (p PersonSlice) Less(i, j int) bool {
return p[i].Age < p[j].Age
}
// Swap method
func (p PersonSlice) Swap(i, j int) {
p[i], p[j] = p[j], p[i]
}Since the comparison is based on age, the result is sorted by age.
func main() {
persons := []Person{{
UserId: "1",
Username: "wyh",
Age: 18,
Address: "us",
}, {
UserId: "2",
Username: "jack",
Age: 17,
Address: "ch",
}, {
UserId: "3",
Username: "mike",
Age: 15,
Address: "india",
}}
sort.Sort(PersonSlice(persons))
fmt.Println(persons)
}Is Sorted
Determine whether a slice is sorted. Internally, it does not perform sorting operations, but determines by looping through calls to Less():
func main() {
persons := []Person{{
UserId: "1",
Username: "wyh",
Age: 18,
Address: "us",
}, {
UserId: "2",
Username: "jack",
Age: 17,
Address: "ch",
}, {
UserId: "3",
Username: "mike",
Age: 15,
Address: "india",
}}
sort.Sort(PersonSlice(persons))
println(sort.IsSorted(PersonSlice(persons)))
}Complete Example
The program below runs as-is: copy it into a file and execute go run main.go, or paste it into the Go Playground.
package main
import (
"fmt"
"sort"
)
type User struct {
Name string
Age int
}
func main() {
users := []User{{"Bob", 30}, {"Alice", 25}, {"Carol", 30}}
sort.SliceStable(users, func(i, j int) bool { return users[i].Age < users[j].Age })
fmt.Println(users)
nums := []int{3, 1, 2}
sort.Ints(nums)
fmt.Println(nums, sort.SearchInts(nums, 2))
}Expected output:
[{Alice 25} {Bob 30} {Carol 30}]
[1 2 3] 1Common Pitfalls
sort.Sliceis not stable. Equal elements may swap; usesort.SliceStablewhen the original order matters.- The less function must be a strict weak ordering. Returning
<=instead of<produces undefined results. sort.Search*requires sorted data. Searching an unsorted slice silently returns wrong indexes.- Keep
Lesscheap. It runs O(n log n) times; precompute expensive comparisons. - Prefer the typed helpers.
sort.Ints,sort.Stringsandsort.SliceStablecover most needs.
Change Log
- 2026-10-14: Added "Before You Start" notes, a complete runnable example with expected output, common pitfalls, and this change log. Closed a code block that was left unterminated.
