跳到主要内容

sort 与 slices

问题

Go 的排序怎么用?sort.Interface 和泛型排序有什么区别?

答案

sort 包(传统方式)

sort.Interface

type Interface interface {
Len() int
Less(i, j int) bool
Swap(i, j int)
}
type ByAge []User

func (a ByAge) Len() int { return len(a) }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func (a ByAge) Swap(i, j int) { a[i], a[j] = a[j], a[i] }

sort.Sort(ByAge(users))

sort.Slice(简化版)

sort.Slice(users, func(i, j int) bool {
return users[i].Age < users[j].Age
})

slices 包(Go 1.21+,推荐)

import "slices"

// 泛型排序
slices.Sort(nums) // 升序(要求 constraints.Ordered)

// 自定义比较
slices.SortFunc(users, func(a, b User) int {
return cmp.Compare(a.Age, b.Age) // -1, 0, 1
})

// 稳定排序
slices.SortStableFunc(users, func(a, b User) int {
return cmp.Compare(a.Age, b.Age)
})

// 二分查找
idx, found := slices.BinarySearch(sorted, target)

sort.Slice vs slices.SortFunc

维度sort.Sliceslices.SortFunc
类型安全弱(基于 interface{}强(泛型)
性能较慢(interface 装箱)较快(无装箱)
比较函数func(i, j int) boolfunc(a, b T) int
推荐Go 1.21 之前Go 1.21+

常见面试问题

Q1: Go 的 sort.Sort 用的什么算法?

答案

混合排序:

  • 数据量大时用快速排序
  • 快排递归深度过大时切换为堆排序(IntroSort)
  • 数据量小时用插入排序

时间复杂度 O(nlogn)O(n \log n),不稳定。需要稳定排序用 sort.Stable

Q2: cmp.Compare 返回什么?

答案

cmp.Compare(a, b)
// a < b → -1
// a == b → 0
// a > b → +1

这是 Go 1.21 引入的标准比较函数,替代了手写 if a < b { return -1 } ...

相关链接