目前,golang還不支持模板函數(類型參數化),因此看上去不得不爲每一種類型都實現一個函數。可是Golang能夠利用空接口interface{}和閉包/高階函數來實現泛型函數。golang
1 空接口閉包
空接口interface{}是指方法集爲空的接口,任何類型的值均可以賦值給空接口。接口相關內容請參見另外一篇博客《Golang中的接口》
app
// interface{} func minimum(first interface{}, rest ...interface{}) interface{} { minimum := first for _, x := range rest { switch x := x.(type) { case int: if x < minimum.(int) { minimum = x } case float64: if x < minimum.(float64) { minimum = float64(x) } case string: if x < minimum.(string) { minimum = string(x) } } } return minimum } func main() { i := minimum(4, 5, 1, 9, 0, -1, -5, 7) fmt.Println(i) j := minimum(4.5, 5.2, -0.4, 9.9, 2.1) fmt.Println(j) k := minimum("abc", "def", "xyz", "ctz", "{}", "#$%^&* ", "中國") fmt.Println(k) }
運行結果
ide
2 閉包/高階函數函數
所謂閉包就是一個函數「捕獲」了和它在同一做用於的其餘常量和變量,從形式上看匿名函數都是閉包。閉包相關內容請參見另外一篇博客《golang閉包》spa
// closure funcfilter(limit int, predicate func(int) bool, appender func(int)) { for i := 0; i < limit; i++ { if predicate(i) { appender(i) } } } func main() { a := []int{4, -3, -8, 9, 0, 2, 1} even := []int{} filter(len(a), func(i int) bool { returna[i]%2 == 0 }, func(i int) { even = append(even, a[i]) }) fmt.Println(even) }
運行結果rest
上述兩個例子很是巧妙的實現了泛型功能,可見golang「難以置信的靈活和強大」。blog
不過,至於golang爲什麼不實現相似C++的模板我還不太理解,在實踐中慢慢感悟吧。接口