本篇文章轉(zhuǎn)載自 在go中使用"泛型"
在進(jìn)入泛型的話題之前, 首先實(shí)現(xiàn)對(duì)int 數(shù)組切片的冒泡排序:
func BubbleSort(array []int) {
for i := 0; i < len(array); i++ {
for j := 0; j < len(array)-i-1; j++ {
if array[j] > array[j+1] {
// 交換
array[j], array[j+1] = array[j+1], array[j]
}
}
}
}
如你所見, 上面的代碼僅適用于對(duì)int數(shù)組進(jìn)行排序, 如果想要對(duì)string數(shù)組排序, 不得不另寫一個(gè)。是否可以只寫一個(gè)通用的泛型程序, 以便對(duì)所有類型的數(shù)組(甚至是任意數(shù)據(jù))進(jìn)行冒泡排序?
很遺憾, go不支持java中的標(biāo)記式泛型. 但是我們可以使用go的interface實(shí)現(xiàn)類似的功能腕让。interface用于定義方法的集合.
在冒泡排序中, 我們可以將排序操作分解成3個(gè)方法: Len()方法負(fù)責(zé)計(jì)算長(zhǎng)度, Less(i, j)方法負(fù)責(zé)比較大小, Swap(i, j)方法負(fù)責(zé)進(jìn)行交換.
// 定義可排序接口
type Sortable interface {
Len() int
Less(int, int) bool
Swap(int, int)
}
可以說, 任何實(shí)現(xiàn)了Sortable接口的數(shù)據(jù)類型都可進(jìn)行冒泡排序, 下面是對(duì)Bubblesort方法的改造:
func BubbleSortable(arr Sortable) {
length := arr.Len()
for i := 0; i < length; i++ {
for j := i; j < length-i-1; j++ {
if arr.Less(j, j+1) {
arr.Swap(j, j+1)
}
}
}
}
BubbleSortable函數(shù)可以對(duì)所有Sortable類型的數(shù)據(jù)進(jìn)行排序. 那么, 哪些數(shù)據(jù)是Sortable類型的呢? 很簡(jiǎn)單, 那些實(shí)現(xiàn)了Len(), Less(i, j), Swap(i, j)方法的數(shù)據(jù)類型都是Sortable的.
如果想要對(duì)int數(shù)組進(jìn)行冒泡排序, 只需讓int數(shù)組實(shí)現(xiàn)以上3個(gè)方法即可:
// 定義IntArr類型
type IntArr []int
// 給IntArr提供Len方法
func (arr IntArr) Len() int {
return len(arr)
}
// 給IntArr提供Less方法
func (arr IntArr) Less(i int, j int) bool {
return arr[i] < arr[j]
}
// 給IntArr提供Swap方法
func (arr IntArr) Swap(i int, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
至此, 我們定義了新的類型: IntArr(實(shí)際上就是int數(shù)組), 并為IntArr增加了Len, Less, Swap方法.
注意, 在go中, 實(shí)現(xiàn)接口不需要像java那樣顯式的說明對(duì)某個(gè)接口的implements, 只需要為類型提供所有interface中定義的方法即可. 此例中, 我們給IntArr提供了所有Sortable中定義的方法, 所以IntArr已經(jīng)實(shí)現(xiàn)了Sortable接口. 接下來要做的是將IntArr類型的數(shù)據(jù)傳遞給BubbleSortable函數(shù)就可以了:
func main() {
intarr := IntArr{2, 3, 1, -9, 0}
// 調(diào)用排序方法
BubbleSortable(intarr)
// 輸出排序之后的數(shù)據(jù)
fmt.Printf("sorted int arr is: %v\n", intarr)
}
同樣的, 如果想對(duì)string數(shù)組進(jìn)行冒泡排序, 也只需要讓string數(shù)組實(shí)現(xiàn)Sortable接口中定義的所有方法:
type StrArr []string
func (arr StrArr) Len() int {
return len(arr)
}
func (arr StrArr) Less(i int, j int) bool {
return arr[i] < arr[j]
}
func (arr StrArr) Swap(i int, j int) {
arr[i], arr[j] = arr[j], arr[i]
}
測(cè)試代碼如下:
func main() {
strarr := StrArr{"nut", "ape", "elephant", "zoo", "go"}
BubbleSortable(strarr)
fmt.Printf("sorted string arr is: %v\n", strarr)
}
現(xiàn)在, 你可以對(duì)任意數(shù)據(jù)進(jìn)行冒泡排序了, 只需要該類型實(shí)現(xiàn)了Len, Less, Swap方法.