先說明下是什麼場景:業務須要對全部的請求參數按照key的大小進行排序而後將其拼成一個字符串,說到這裏你們可能就明白其實這就是一個驗證請求籤名的東西。那在php中對key-value結構按照key來排序直接使用ksort函數就能夠了,可是在go中並無給定這樣的方法,須要本身來實現。php
事實上,在go的sort包中,只提供了幾種最簡單的數據類型的排序,分別是int string float64類型的slice,能夠說,基本上全部的排序都須要工程師本身來擴展,好在,在go中擴展這樣的排序方法很簡單。算法
先來看看sort包源碼是怎麼作的:app
// A type, typically a collection, that satisfies sort.Interface can be // sorted by the routines in this package. 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) }
在源碼go/src/sort/sort.go裏,根據註釋能夠清晰的看到sort包定義了一個interface類型sort.Interface, 只要是實現了Len, Less和Swap三種方法的數據類型就可以直接調用sort.Sort()方法進行排序。而不須要關心sort內部究竟用哪一種算法實現了排序。函數
再細緻的看一下,sort包內部實現了四種排序算法,插入,歸併,堆排序和快速排序。這三種方法都是私有的,在程序調用Sort()函數時,該函數會根據輸入的狀況動態決定使用何種排序算法,即sort包向咱們隱藏了排序具體的實現方式。感興趣的同窗能夠看一下Sort()函數是如何作的。this
接下來就看下如何對一個map結構根據key來進行排序:spa
//map排序,按key排序 type MapSorter []MapItem func NewMapSorter(m map[string]string) MapSorter { ms := make(MapSorter, 0, len(m)) for k, v := range m { ms = append(ms, MapItem{Key: k, Val: v}) } return ms } type MapItem struct { Key string Val string } func (ms MapSorter) Len() int { return len(ms) } func (ms MapSorter) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] } //按鍵排序 func (ms MapSorter) Less(i, j int) bool { return ms[i].Key < ms[j].Key }
主要思路就是定義一個struct,它的兩個屬性分別對應於map的key/value,Less函數中對key值進行大小對比。相信看一下上面的代碼,你們就能明白這段代碼該如何寫。。。code