在go中使用"泛型"


在go中使用"泛型"

[2012-05-21 翻譯自 這里, 對原文有所擴展, 也有所刪減.]
 
在進入泛型的話題之前, 首先實現對int slice(可以看做int數組)的冒泡排序:
復制代碼
 1 func BubbleSort(array []int) {
 2     for i := 0; i < len(array); i++ {
 3         for j := 0; j < len(array)-i-1; j++ {
 4             if array[j] > array[j+1] {
 5                 // 交換
 6                 array[j], array[j+1] = array[j+1], array[j]
 7             }
 8         }
 9     }
10 } 
復制代碼
如你所見, 上面的代碼僅適用於對int數組進行排序, 如果想要對string數組排序, 不得不另寫一個. 
是否可以只寫一個通用的泛型程序, 以便對所有類型的數組(甚至是任意數據)進行冒泡排序?
 
很遺憾, go不支持java中的標記式泛型. 但是我們可以使用go的interface實現類似的功能.
interface用於定義方法的集合. 在冒泡排序中, 我們可以將排序操作分解成3個方法: Len()方法負責計算長度, Less(i, j)方法負責比較大小, Swap(i, j)方法負責進行交換.
復制代碼
1 // 定義可排序接口
2 type Sortable interface {
3     Len() int
4     Less(int, int) bool
5     Swap(int, int)
6 }
復制代碼
可以說, 任何實現了Sortable接口的數據類型都可進行冒泡排序, 下面是對Bubblesort方法的改造:
復制代碼
 1 func BubbleSortable(arr Sortable) {
 2     length := arr.Len()
 3     for i := 0; i < length; i++ {
 4         for j := i; j < length-i-1; j++ {
 5             if arr.Less(j, j+1) {
 6                 arr.Swap(j, j+1)
 7             }
 8         }
 9     }
10 } 
復制代碼
BubbleSortable函數可以對所有Sortable類型的數據進行排序. 那么, 哪些數據是Sortable類型的呢? 很簡單, 那些實現了Len(), Less(i, j), Swap(i, j)方法的數據類型都是Sortable的. 
 
如果想要對int數組進行冒泡排序, 只需讓int數組實現以上3個方法即可:
復制代碼
 1 // 定義IntArr類型
 2 type IntArr []int
 3 // 給IntArr提供Len方法
 4 func (arr IntArr) Len() int {
 5     return len(arr)
 6 }
 7 // 給IntArr提供Less方法
 8 func (arr IntArr) Less(i int, j int) bool {
 9     return arr[i] < arr[j]
10 }
11 // 給IntArr提供Swap方法
12 func (arr IntArr) Swap(i int, j int) {
13     arr[i], arr[j] = arr[j], arr[i]
14 } 
復制代碼
至此, 我們定義了新的類型: IntArr(實際上就是int數組), 並為IntArr增加了Len, Less, Swap方法.
注意, 在go中, 實現接口不需要像java那樣顯式的說明對某個接口的implements, 只需要為類型提供所有interface中定義的方法即可. 此例中, 我們給IntArr提供了所有Sortable中定義的方法, 所以IntArr已經實現了Sortable接口. 接下來要做的是將IntArr類型的數據傳遞給BubbleSortable函數就可以了:
1 intarr := IntArr{2, 3, 1, -9, 0}
2 // 調用排序方法
3 BubbleSortable(intarr)
4 // 輸出排序之后的數據
5 fmt.Printf("sorted int arr is: %v\n", intarr)
 
同樣的, 如果想對string數組進行冒泡排序, 也只需要讓string數組實現Sortable接口中定義的所有方法:
復制代碼
 1 type StrArr []string
 2 func (arr StrArr) Len() int {
 3     return len(arr)
 4 }
 5 func (arr StrArr) Less(i int, j int) bool {
 6     return arr[i] < arr[j]
 7 }
 8 func (arr StrArr) Swap(i int, j int) {
 9     arr[i], arr[j] = arr[j], arr[i]
10 } 
復制代碼
測試代碼如下:
1 strarr := StrArr{"nut", "ape", "elephant", "zoo", "go"}
2 Bubblesort(strarr)
3 fmt.Printf("sorted string arr is: %v\n", strarr)
 
現在, 你可以對任意數據進行冒泡排序了, 只需要該類型實現了Len, Less, Swap方法.
本文由本人原創或者翻譯. 歡迎轉載原創文章, 但轉載必須保存本簽名. 對於翻譯文章, 所有版權屬於原作者, 轉載必須保存本簽名. from: http://www.cnblogs.com/cool-xing


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM