Go语言中是否有类似PHP usort、支持返回-1/0/1比较规则的排序实现
Go语言与PHP usort对等的排序实现说明
原生支持(Go 1.21及以上版本)
Go 1.21版本后标准库sort包提供了完全匹配PHP usort语义的API,无需额外封装即可直接使用:
- 比较函数签名为
func(a, b T) int,和PHP的cmp函数逻辑完全对齐,直接返回-1、0、1即可定义排序规则 - 不需要额外实现接口,直接将自定义比较逻辑作为参数传入
sort.SortFunc即可完成排序
以下是和你给出的PHP示例完全等价的Go实现:
package main import ( "fmt" "sort" ) func main() { // 对应PHP示例的数组,usort会丢弃原关联键,直接用切片存储值即可 nums := []int{4, 8, -1, -9, 2, 3, 5, -4} // 自定义比较逻辑,和PHP的cmp函数完全一致 cmp := func(a, b int) int { if a == b { return 0 } if a < b { return -1 } return 1 } // 直接调用完成排序 sort.SortFunc(nums, cmp) // 输出结果和PHP示例完全一致:[-9 -4 -1 2 3 4 5 8] fmt.Println(nums) }
如果需要保持相等元素的相对顺序(稳定排序),可以改用sort.StableFunc,参数和SortFunc完全一致。
低版本Go适配(<1.21)
低版本Go的sort包原生API要求实现sort.Interface接口(包含Len()、Swap()、Less()三个方法),其中Less方法仅返回布尔值,没有直接支持返回-1/0/1的比较函数,可通过简易适配器实现等价逻辑:
package main import ( "fmt" "sort" ) // 通用适配器,将返回int的比较函数转换为sort.Interface要求的Less逻辑 type ComparableSlice[T any] struct { Data []T Cmp func(a, b T) int } func (s ComparableSlice[T]) Len() int { return len(s.Data) } func (s ComparableSlice[T]) Swap(i, j int) { s.Data[i], s.Data[j] = s.Data[j], s.Data[i] } func (s ComparableSlice[T]) Less(i, j int) bool { return s.Cmp(s.Data[i], s.Data[j]) < 0 } func main() { nums := []int{4, 8, -1, -9, 2, 3, 5, -4} cmp := func(a, b int) int { if a == b { return 0 } if a < b { return -1 } return 1 } // 传入适配器实例完成排序 sort.Sort(ComparableSlice[int]{Data: nums, Cmp: cmp}) fmt.Println(nums) }
如果使用的是Go 1.18以下不支持泛型的版本,只需将泛型定义替换为对应具体类型(如把T替换为int)即可正常使用。
语义差异说明
- 同PHP的usort一致,排序会直接修改原切片/数组的元素顺序,不会保留原下标/键的关联(如果需要保留键的对应关系,需要自行封装结构体存储键值对再排序)
- 比较函数返回值语义完全对齐:返回负数代表a需排在b前面,返回0代表元素相等,返回正数代表a需排在b后面
内容的提问来源于stack exchange,提问作者BoodyBruh
相关产品推荐
相关产品推荐

