在日常开发中,排序是非常常见的操作,例如对数组排序、对结构体切片排序、排行榜、数据分析等。Go 标准库中的
sort包提供了一整套高效且灵活的排序工具,可以对各种数据结构进行排序。
sort 的设计非常优雅,它既支持对基础类型排序,也支持自定义排序逻辑。掌握 sort,基本可以覆盖所有常见排序需求。
在最简单的场景下,如果只是对基础类型排序,比如 int、float64 或 string,可以直接使用内置函数。
go
package main
import (
"fmt"
"sort"
)
func main() {
nums := []int{5, 2, 8, 1, 3}
sort.Ints(nums)
fmt.Println(nums)
}
输出结果:
csharp
[1 2 3 5 8]
类似的函数还有:
text
sort.Float64s
sort.Strings
这些函数使用简单,适合大多数基础排序场景。
如果需要判断一个切片是否已经排序,可以使用:
go
sort.IntsAreSorted(nums)
返回值是 true 或 false。
在实际开发中,更常见的是对结构体进行排序。例如有一个用户列表,需要按年龄排序。
go
type User struct {
Name string
Age int
}
users := []User{
{"Alice", 30},
{"Bob", 20},
{"Tom", 25},
}
这时就需要自定义排序逻辑。Go 提供了两种方式。
第一种方式是实现 sort.Interface。
go
type ByAge []User
func (a ByAge) Len() int { return len(a) }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
然后调用排序:
go
sort.Sort(ByAge(users))
输出:
css
[{Bob 20} {Tom 25} {Alice 30}]
这种方式比较底层,但非常灵活,可以实现复杂排序逻辑。
不过在现代 Go 开发中,更推荐使用 sort.Slice(),写法更加简洁。
go
sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
这种方式不需要定义额外类型,非常适合快速开发。
如果需要倒序排序,只需调整比较逻辑:
go
sort.Slice(users, func(i, j int) bool {
return users[i].Age > users[j].Age
})
除了普通排序,Go 还支持稳定排序。稳定排序的特点是:当两个元素相等时,保持原有顺序不变。
go
sort.SliceStable(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})
适用于:
多字段排序 需要保持原顺序的场景
例如先按年龄排序,再按名字排序。
sort 包还提供了反转排序的能力:
go
sort.Sort(sort.Reverse(sort.IntSlice(nums)))
输出:
csharp
[8 5 3 2 1]
在某些场景中,我们不仅需要排序,还需要查找。sort 提供了二分查找函数 Search()。
go
i := sort.Search(len(nums), func(i int) bool {
return nums[i] >= 3
})
这个函数会返回第一个满足条件的位置。
前提是数据必须是已排序的。
实际开发中,sort 的应用非常广泛。例如:
排行榜系统(按分数排序) 商品列表排序(价格、销量) 日志排序(时间) 数据分析(升序/降序)
例如一个简单排行榜:
go
type Player struct {
Name string
Score int
}
players := []Player{
{"A", 100},
{"B", 200},
{"C", 150},
}
sort.Slice(players, func(i, j int) bool {
return players[i].Score > players[j].Score
})
需要注意的是,sort 默认排序是原地排序(in-place),也就是说会直接修改原切片。如果需要保留原数据,需要先复制一份。
go
copyData := append([]int(nil), nums...)
sort.Ints(copyData)
在性能方面,Go 的 sort 使用的是高效排序算法(混合快速排序等),在大多数场景下性能都非常优秀。一般不需要自己实现排序算法。
总结来看,sort 是 Go 标准库中用于排序和查找的核心工具,它提供了从简单到复杂的一整套解决方案:
基础排序:Ints、Strings、Float64s 自定义排序:Sort、Slice 稳定排序:SliceStable 反向排序:Reverse 查找:Search
在实际开发中,如果是基础类型直接使用 sort.Ints 等函数;如果是结构体排序,优先使用 sort.Slice;如果需要稳定排序,则使用 SliceStable。掌握这些方法,就可以轻松应对绝大多数排序需求。
对于任何涉及数据处理、列表展示或排名逻辑的 Go 项目来说,sort 都是一个必须熟练掌握的基础工具库。