GO中的「泛型」?

Golang不支持通常的相似Java中的標記式泛型。不少人所以而十分不滿,認爲沒有泛型增長了不少工做量。而目前因爲泛型支持的複雜性,Golang的設計和實現者並無把這個泛型支持做爲緊急須要增長的特性。可是,若是真的沒有泛型,就必定不行了麼?答案固然是否認的。沒有泛型也能夠,並且我以爲代碼更簡單,直接,有趣(我的觀點,勿噴)。java

咱們這裏打算以一些例子來說解Golang中如何處理這個問題。數組

首先,咱們看一個冒泡排序的問題。針對整型數組切片的排序。函數

package main

import (
	"fmt"
)

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]
			}
		}
	}
}

func main() {
	a1 := []int{3, 2, 6, 10, 7, 4, 6, 5}
	bubbleSort(a1)
	fmt.Println(a1)
}

在線運行地址:https://www.bytelang.com/o/s/c/H8uLEIC6dA0=測試

 

上面的例子輸出爲:spa

[2 3 4 5 6 6 7 10]

那麼,咱們若是但願這個bubbleSort可以同時支持float類型數據排序,或者是按照字符串的長度來排序應該怎麼作呢?在其餘的例如java語言中,咱們能夠將bubbleSort定義爲支持泛型的排序,可是Go裏面就不行了。爲了達到這個目的,咱們可使用interface來實現相同的功能。.net

針對上面的排序問題,咱們能夠分析一下排序的步驟:設計

  1. 查看切片長度,以用來遍歷元素(Len);
  2. 比較切片中的兩個元素(Less);
  3. 根據比較的結果決定是否交換元素位置(Swap)。
    到這裏,或許你已經明白了,咱們能夠把上面的函數分解爲一個支持任意類型的接口,任何其餘類型的數據只要實現了這個接口,就能夠用這個接口中的函數來排序了。
type Sortable interface{
	Len() int
	Less(int, int) bool
	Swap(int, int)
}

下面,咱們就用幾個例子來描述一下這個接口的用法。code

 

package main

import (
	"fmt"
)

type Sortable interface {
	Len() int
	Less(int, int) bool
	Swap(int, int)
}

func bubbleSort(array Sortable) {
	for i := 0; i < array.Len(); i++ {
		for j := 0; j < array.Len()-i-1; j++ {
			if array.Less(j+1, j) {
				array.Swap(j, j+1)
			}
		}
	}
}

//實現接口的整型切片
type IntArr []int

func (array IntArr) Len() int {
	return len(array)
}

func (array IntArr) Less(i int, j int) bool {
	return array[i] < array[j]
}

func (array IntArr) Swap(i int, j int) {
	array[i], array[j] = array[j], array[i]
}

//實現接口的字符串,按照長度排序
type StringArr []string

func (array StringArr) Len() int {
	return len(array)
}

func (array StringArr) Less(i int, j int) bool {
	return len(array[i]) < len(array[j])
}

func (array StringArr) Swap(i int, j int) {
	array[i], array[j] = array[j], array[i]
}

//測試
func main() {
	intArray1 := IntArr{3, 4, 2, 6, 10, 1}
	bubbleSort(intArray1)
	fmt.Println(intArray1)

	stringArray1 := StringArr{"hello", "i", "am", "go", "lang"}
	bubbleSort(stringArray1)
	fmt.Println(stringArray1)
}

在線運行地址:https://www.bytelang.com/o/s/c/J_thL5dPXxI=排序

 

輸出結果爲:接口

[1 2 3 4 6 10]
[i am go lang hello]

上面的例子中,咱們首先定義了一個IntArr類型的整型切片類型,而後讓這個類型實現了Sortable接口,而後在測試代碼中,這個IntArr類型就能夠直接調用Sortable接口的bubbleSort方法了。

另外,咱們還演示了一個字符串切片類型StringArr按照字符串長度來排序的例子。和IntArr類型同樣,它實現了Sortable便可定義的方法,而後就能夠用Sortable便可的bubbleSort方法來排序了。

總結 上面的例子,是一種Golang中支持所謂的「泛型」的方法。這種泛型固然不是真正意義上面的泛型,可是提供了一種針對多種類型的一致性方法的參考實現。

相關文章
相關標籤/搜索