1.在很多语言中,排序算法跟数据类型绑定,排序函数实现和序列的元素类型绑定,但是go中sort.Sort对序列和其中元素的布局无任何要求,只是使用sort.Interface接口 指定协议
2.任何一个想要排序的类型,只要实现Interface 下面的三个方法即可
package sort
type Interface interface {
Len() int
Less(i, j int) bool // i, j are indices of sequence elements
Swap(i, j int)
}
一个类型如果实现了上面三个方法,如下,就可以使用 sort.Sort来排序
type IntSlice []int
func (x IntSlice) Len() int { return len(x) }
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
var x IntSlice
x = []int{1,2,3,0}
sort.Sort(x)//0,1,2,3
3.想要实现倒序排序,sort包提供了Reverse方法
sort.Sort(sort.Reverse(x))
下面具体解释Reverse方法的实现
sort包里面有个未导出的结构体reverse,使用了组合方式,结构体内部内嵌了sort.Interface结构,所以可以使用他提供的三个方法,但reverse重写了less方法,逻辑还是调用接口的less方法,改动只是交换了传入的下标,就可以颠倒排序的结果,所以reverse的另外两个方法由内嵌的接口隐式提供,具体方法的地址在接口赋值的时候由接口的动态类型决定。Reserve函数只是返回一个包含原始sort.Interface值的reverse实例,类比于原生的Interface,只不过他的less函数和sort.Interface的反了过来,所以如果实现倒序,还是要用sort.Sort方法,里面传入reverse实例,sort.Sort(sort.Reverse(x))
type reverse struct {
// This embedded Interface permits Reverse to use the methods of
// another Interface implementation.
Interface
}
// Less returns the opposite of the embedded implementation's Less method.
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
// Reverse returns the reverse order for data.
func Reverse(data Interface) Interface {
return &reverse{data}
}