go 中的切片排序
Go 语言的 sort.Sort 函数不会对具体的序列和它的元素做任何假设。相反,它使用了一个接口类型 sort.Interface 来指定通用的排序算法和可能被排序到的序列类型之间的约定。这个接口的实现由序列的具体表示和它希望排序的元素决定,序列的表示经常是一个切片。
实现排序有 2 个方法
调用 Sort 包的 Slice 方法
该方法是 go1.8 版本后支持的,调用 sort 包的 Slice 函数,该函数的签名如下:
1 | |
x 参数是一个自定义对象切片,less 参数是一个函数对象,该函数对象需要传入 2 个参数,返回 bool 值,该函数就是自定义对象实现排序的依据
1 | |
以上代码实现了菜单的排序,根据菜单的 Sort 字段进行升序排序。
实现 Interface 接口
一个内置的排序算法需要知道三个东西:序列的长度,表示两个元素比较的结果,一种交换两个元素的方式;这就是 sort.Interface 的三个方法:
需要实现的接口
1 | |
实现接口
为了对序列进行排序,我们需要定义一个实现了这三个方法的类型,然后对这个类型的一个实例应用 sort.Sort 函数。那么就要给该对象起一个别名,例子如下:
1 | |
注意,这里必须得是起别名,不这样的话该接口的 Swap 函数就无法实现元素交换
在 Less 函数和 Swap 函数都起到了排序实现,首先会是 Less 函数,该函数会让切片里的 i 元素的 Sort 字段和 j 元素的 Sort 字段进行比较并返回比较结果,而 Swap 函数使用 Go 语言的多变量赋值特性实现元素交换。
在以上例子中就根据了切片元素中的 Sort 字段进行比较判断,判断 i 元素小于 j 元素则返回 true,结果将会是升序排序。
使用排序
在给需要排序的对象实现接口之后,就可以在业务代码里面进行调用了。
调用很简单,就需要写以下代码:
1 | |
调用 sort 包的 Sort 方法,传入实现了 Interface 接口的结构体。
常见类型的便捷排序
对字符串切片进行升序排序
使用 sort.Strings 直接对字符串切片进行排序。
1 | |
sort 包内的内建类型排序
| 类 型 | 实现 sort.lnterface 的类型 | 直接排序方法 | 说 明 |
|---|---|---|---|
| 字符串(String) | StringSlice | sort.Strings(a [] string) | 字符 ASCII 值升序 |
| 整型(int) | IntSlice | sort.Ints(a []int) | 数值升序 |
| 双精度浮点(float64) | Float64Slice | sort.Float64s(a []float64) | 数值升序 |