go1.18泛型的簡單嘗試

aaayi發表於2022-03-16

今天golang終於釋出了1.18版本,這個版本最大的一個改變就是加入了泛型。雖然沒有在beta版本的時候嘗試泛型,但是由於在其他語言的泛型經驗,入手泛型不是件難事~

官方示例

Tutorial: Getting started with generics - The Go Programming Language

根據官方示例可以看出,在go中泛型宣告使用中括號,大體用法也與其他語言差不多。下面就官方示例中出現的幾個點做記錄。

comparable

在泛型的約束中有 comparable 關鍵字,我們進到原始碼中看到解釋:

// comparable is an interface that is implemented by all comparable types
// (booleans, numbers, strings, pointers, channels, arrays of comparable types,
// structs whose fields are all comparable types).
// The comparable interface may only be used as a type parameter constraint,
// not as the type of a variable.
type comparable interface{ comparable }

看得出來這是官方定義的一個可比較的型別的一個泛型約束,它也只能存在於型別引數約束的時候。

一些改變

我們嘗試修改官方示例,體驗一下其他的關鍵詞及相關用法。

~ 波浪號

我們會在一些泛型示例中看到這樣的宣告:

type Number interface {
	~int64 | float64 | string
}

~ 在這裡應該可以理解為 泛型別 ,即所有以int64為基礎型別的型別都能夠被約束。

我們來舉個例子:現在我們宣告一個以 int64 為基礎型別,取名為testInt

type testInt int64

type Number interface {
	~int64
}

func SumIntsOrFloats[K comparable, V Number](m map[K]V) V {
	var s V
	for _, v := range m {
		s += v
	}
	return s
}

func main() {
	ints := map[string]testInt{
		"first":  34,
		"second": 12,
	}

	fmt.Printf("Generic Sums: %v\n",
		SumIntsOrFloats(ints))
}

在這個示例中,可以看到我們將testInt作為自定義型別傳入了泛型方法中,在這種情況下,如果不給Number中的int64~,這裡就會報錯。加上~之後代表以int64為基本型別的自定義型別也可以通過泛型約束

未釋出的內容

在泛型的測試階段,有一個 constraints 包被加入到原始碼中,這個包裡面宣告瞭一些官方定義的約束,但是在正式的釋出版中卻被去掉了。

相關文章