這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
sort 包的核心類型是 sort.Interface:
type Interface interface { // Len is the number of elements in the collection. Len() int // Less reports whether the element with // index i should sort before the element with index j. Less(i, j int) bool // Swap swaps the elements with indexes i and j. Swap(i, j int)}
介面 是golang 的很cool 的特性,rob pike 說介面有點類似uinx pipe,把不同的程式碼片段串連在一起,這個契約就是介面規範,
提供了指定的功能集合,不管你的內部實現。var s sort.Interface, s 是抽象的介面類型, 具體類型u只要提供了 Len(), Less(), Swap(), s = u, 就可以把 u 型變數賦值s, 還體現在 函數函數 是 s, 傳回值是s 的地方。
sort.Ints, sort.Float64s, sort.Strings, 都是庫方便的封裝,如 sort.Ints 是這樣實現的:
func Ints(a []int) { Sort(IntSlice(a)) }
type IntSlice []int func (p IntSlice) Len() int { return len(p) } func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] } func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
內部調用 sort.Sort(), 函數的參數是抽象的sort.Interface 類型,[]int 類型沒有實現Len(), Less(), Swap() , 而它的別名資料型別
IntSlice 實現了, 所以 IntSlice(a), 類型轉換,以滿足介面。對於反序排序有一個巧妙的介面運用:
type reverse struct { Interface }
func (r reverse) Less(i, j int) bool {
return r.Interface.Less(j, i)
}
func Reverse(data Interface) Interface {
return &reverse{data}
}
golang語言規範如下描述:
Given a struct type S
and a type named T
, promoted methods are included in the method set of the struct as follows:
The method set of an interface type is its interface。
reverse struct 類型 是S, Interface 是T, reverse 包含匿名欄位 Interface, Interface 是介面類型,它的方法集是自己, Len(), Swap(), Less() 被提升到 reverse上, 而reverse又定義的自己的Less()(內部引用被嵌入欄位的實現,翻轉比較), reverse 類型擁有了老的len(),swap() 實現,新的less() 實現,所以滿足 sort.Interface, reverse 的指標類型包含reverse的方法集,所以
匯出函數Reverse() 返回 reverse 指標來滿足 Interface介面。
package mainimport ( "fmt" "sort")func bubbleSort(data sort.Interface){ r := data.Len()-1 for i := 0; i < r ; i++{ for j := r; j > i; j--{ if data.Less(j, j-1){ data.Swap(j, j-1) } } }}func insertSort(data sort.Interface){ r := data.Len()-1 for i := 1; i <= r; i++{ for j := i; j > 0 && data.Less(j, j-1); j--{ data.Swap(j, j-1) } }}func selectSort(data sort.Interface){ r := data.Len()-1 for i := 0; i < r; i++{ min := i for j:= i+1; j <= r; j++ { if data.Less(j, min) { min = j } } data.Swap(i, min) }}func main(){ nums := []int{120,33,44,1,23,90,87,13,57,43,42} //標準庫qsort 正序(實際上是qsort結合heapsort,insertsort) sort.Ints(nums) fmt.Println(nums) //反序qsort sort.Sort(sort.Reverse(sort.IntSlice(nums))) fmt.Println(nums) //正序bubble bubbleSort(sort.IntSlice(nums)) fmt.Println(nums) //反序bubble bubbleSort(sort.Reverse(sort.IntSlice(nums))) fmt.Println(nums) //正序insert insertSort(sort.IntSlice(nums)) fmt.Println(nums) //反序inert insertSort(sort.Reverse(sort.IntSlice(nums))) fmt.Println(nums) //正序select selectSort(sort.IntSlice(nums)) fmt.Println(nums) //反序select selectSort(sort.Reverse(sort.IntSlice(nums))) fmt.Println(nums)}