背景
今天有小伙伴问Go里面如何给自定义类型排序,然后我让她实现了一下sort包里面的几个方法,当然就是Len(),Less()和Swap()了,常规操作,不过她额外在代码里面加了一个逆序排序的操作,我CodeReview的时候看了一把,顿时有些疑惑。代码大概类似下面这个:
package main
import (
"sort"
"fmt"
)
func main() {
var s = []int{4, 3, 6, 7, 3, 1}
sort.Sort(sort.Reverse(sort.IntSlice(s)))
fmt.Println(s)
}
本来我觉得至少得这么写,先排序,再逆序一把,就像这样(实际不行):
sort.Sort(sort.IntSlice(s))
sort.Reverse(sort.IntSlice(s))
解惑
出于好奇,我翻了下Go的源码,发现了端倪:
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}
}
这个 Reverse 方法没那么简单,它是在传入的参数之上有封装了一个 reverse 类型,这个类型通过组合的方式继承了传入参数的排序接口实现,但是在这里它覆盖了原传入参数类型的Less()方法,而实际上再交给 sort.Sort() 函数进行排序的类型已经是新的 reverse 类型了,十分有意思的技巧,代码虽少,但是阐述了Go里面组合类型的使用方法。