欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang中的泛型你真的了解嗎

 更新時間:2023年05月12日 10:52:51   作者:程序員祝融  
Golang?在?1.18?版本更新后引入了泛型,這是一個重要的更新,Gopher?萬眾矚目,為?Golang?帶來了更多的靈活性和可重用性,今天,我們將深入探討泛型的概念、為什么需要泛型、泛型的語法,并探討如何在實踐中使用它

Golang 在 1.18 版本更新后引入了泛型,這是一個重要的更新,Gopher 萬眾矚目,為 Golang 帶來了更多的靈活性和可重用性,同時也解決了在特定場景下 Golang 類型系統(tǒng)的限制。

今天,我們將深入探討泛型的概念、為什么需要泛型、泛型的語法,并探討如何在實踐中使用它。

go version >= 1.18

什么是泛型

泛型是一種在軟件開發(fā)中廣泛使用的編程概念,它允許開發(fā)者編寫可重用的代碼,而不需要考慮具體的數(shù)據(jù)類型。使用泛型,開發(fā)者可以編寫一些通用的算法和數(shù)據(jù)結構,這些算法和數(shù)據(jù)結構可以適用于不同類型的數(shù)據(jù),而不需要為每種類型都編寫一份專用的代碼。泛型的概念在其他許多編程語言中都有支持,比如 C++、Java、C# 等。

為什么需要泛型

假設我們需要實現(xiàn)一個返回一個 Map key 的 切片 []int -- MapKeysToInt。

func MapKeysToInt(m map[int]string) []int {
	r := make([]int, 0, len(m))
	for k := range m {
		r = append(r, k)
	}
	return r
}

可是這個函數(shù)只能接收map[int]string 類型的參數(shù),如果我們想支持 int8 類型的參數(shù),我們就需要再定義一個MapKeysToInt8 函數(shù)。

func MapKeysToInt8(m map[int8]string) []int8 {
	r := make([]int8, 0, len(m))
	for k := range m {
		r = append(r, k)
	}
	return r
}

如果要想支持 int64 類型切片就要定義 MapKeysToInt32 函數(shù),如果想支持 xxx 就需要定義一個 MapKeysToXXX...

我們會發(fā)現(xiàn)一遍一遍地編寫相同的功能非常的低效,

func MapKeysToInt32(m map[int32]string) []int32 {
	r := make([]int32, 0, len(m))
	for k := range m {
		r = append(r, k)
	}
	return r
}

Go1.18 之前我們可以使用反射的方式去實現(xiàn)上述問題,但是會降低代碼的執(zhí)行效率且失去編譯期的類型檢查等弊端。

Go1.18 之后我們可以用泛型來實現(xiàn)這一系列問題,eg:

// 當調用泛型函數(shù)的時候, 我們經??梢允褂妙愋屯茢唷?
// 注意,當調用 MapKeys 的時候,我們不需要為 K 和 V 指定類型 - 編譯器會進行自動推斷
func MapKeys[K comparable, V any](m map[K]V) []K {
	r := make([]K, 0, len(m))
	for k := range m {
		r = append(r, k)
	}
	return r
}

func main (){
	var m = map[int]string{
		1: "2",
		2: "4",
		4: "8",
	}
	fmt.Println("keys m:", MapKeys(m))

    var m2 = map[string]int{
		"程序員祝融": 1,
		"李四": 2,
		"王五": 3,
	}
	fmt.Println("keys m2:", MapKeys(m2))
}

// demo 運行結果:
// keys m: [2 4 1]
// keys m2: [李四 王五 程序員祝融]

泛型語法

泛型為Go語言添加了三個新的重要特性:

  • 類型參數(shù)(形參、實參)
  • 類型集
  • 類型推斷

類型參數(shù)

之前我們定義函數(shù)時可以指定其形參,調用函數(shù)時傳實參,如下。

現(xiàn)在,Go 語言中的函數(shù)和類型支持添加類型參數(shù)。類型參數(shù)以類似于函數(shù)參數(shù)的方式進行定義,使用方括號 [] 包含一個或多個類型參數(shù)。

用泛型實現(xiàn)一個比較兩數(shù)大小的 demo ,eg:

func max[T int | int32 | int64 | float32](x, y T) T {
	if x >= y {
		return x
	}
	return y
}

類型實例化

我們定義了一個 max 函數(shù),支持傳 int、int32、int64、float32 類型,我們可以傳入這 4 種類型中的任意一個。 eg 傳一個 int 類型:

max[int32](1, 2) // 2

也支持傳一個 float32 類型:

max[float32](0.1, 0.2) // 0.2

max 函數(shù)提供類型參數(shù)(在本例中為 int 和float32 ) 稱為實例化。eg:

// 類型實例化,編譯器生成 T=float32 的 max 函數(shù)
f := max[float32]
fmt.Println(f(0.1, 0.2))

我們定義了一個 max[float32] 函數(shù) f,我們可以在接下來調用函數(shù)的方式使用 f(0.1, 0.2) 它 。

類型約束

類型約束是指限制類型參數(shù)的類型的約束條件,可以使用interface關鍵字來表示。以上方的 demo,我們常見的方式有:

類型約束接口直接在類型參數(shù)列表中使用:

func max[T interface{ int | int32 | int64 | float32 }](x, y T) T {
	if x >= y {
		return x
	}
	return y
}

也可以事先定義,后復用

// 事先定義類型約束類型
type Value interface {
	int | int32 | int64 | float32 
}
func min[T Value](a, b T) T {
	if a <= b {
		return a
	}
	return b
}

在定義一個可以比較大小的泛型函數(shù)時,可以使用 comparable約束條件來限制類型參數(shù)的類型:

func MapKeys[K comparable, V any](m map[K]V) []K {
	r := make([]K, 0, len(m))
	for k := range m {
		r = append(r, k)
	}
	return r
}

類型集

類型集是泛型語法中用來約束類型參數(shù)的工具,它規(guī)定了類型參數(shù)所能接受的類型范圍。在 Golang 1.18 中,類型集使用 interface 來定義,在類型參數(shù)后面添加 interface 關鍵字來實現(xiàn)的。通俗一點解釋,接口類型現(xiàn)在可以用作值的類型,也可以用作類型約束。

下面是一個定義了類型集的例子:

type MySlice interface {
	int | float32 | string
}

上面這個就表示定義了一個 int、float32、string 的類型集。

any 接口

Go 在 1.18 引入了一個新的預聲明標識符,作為空接口類型的別名。

type any = interface{}

使用 eg:

func Swap[T any](a, b *T) {
    temp := *a
    *a = *b
    *b = temp
}

類型推斷

最后說下類型推斷,非常重要,在go 1.18 后推出,能夠讓開發(fā)者在使用泛型時更加的自然。

參數(shù)類型推斷

對于函數(shù)參數(shù)的類型,需要傳遞類型參數(shù),使得代碼變長??聪乱婚_始的 demo

func max[T int | int32 | int64 | float32](x, y T) T {
	if x >= y {
		return x
	}
	return y
}

調用

var a, b, s int
a := 1
b := 2
s := max[int32](a, b) // 2

在大部分場景下,我們的編譯器其實可以自行推斷類型參數(shù) T。有了這個可以似的我們的代碼變的更短,同事保持清晰。

var a, b, s int
a := 1
b := 2
s := max(a, b) // 2

總結

Go 在 1.18 中引入了泛型這一特性,極大地增強了語言的表現(xiàn)力和靈活性。通過類型參數(shù)、類型集、類型推斷等語法特性,可以方便地定義和使用泛型類型和泛型函數(shù)。同時,編譯器對泛型的支持也在不斷完善,包括對類型參數(shù)的約束、類型集的多態(tài)和類型推斷的增強等,進一步提升了泛型的實用性和性能。

在實際開發(fā)中,泛型可以用來處理許多常見的問題,如集合類的封裝、算法的實現(xiàn)和通用接口的定義等。除了標準庫中已經實現(xiàn)的泛型類型和函數(shù)之外,我們還可以通過自定義泛型類型和函數(shù)來滿足特定的需求。

最后,使用泛型時需要注意類型安全和性能問題,特別是對于大規(guī)模的數(shù)據(jù)處理和算法計算,需要進行細致的測試和優(yōu)化。

到此這篇關于Golang中的泛型你真的了解嗎的文章就介紹到這了,更多相關Golang泛型內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • golang基礎之Gocurrency并發(fā)

    golang基礎之Gocurrency并發(fā)

    這篇文章主要介紹了golang基礎之Gocurrency并發(fā),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Go語言for range(按照鍵值循環(huán))遍歷操作

    Go語言for range(按照鍵值循環(huán))遍歷操作

    這篇文章主要介紹了Go語言for range(按照鍵值循環(huán))遍歷操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言基于viper實現(xiàn)apollo多實例快速

    Go語言基于viper實現(xiàn)apollo多實例快速

    viper是適用于go應用程序的配置解決方案,這款配置管理神器,支持多種類型、開箱即用、極易上手。本文主要介紹了如何基于viper實現(xiàn)apollo多實例快速接入,感興趣的可以了解一下
    2023-01-01
  • Golang實現(xiàn)AES加密和解密的示例代碼

    Golang實現(xiàn)AES加密和解密的示例代碼

    AES( advanced encryption standard)使用相同密鑰進行加密和解密,也就是對稱加密。本文將詳細講解Golang實現(xiàn)AES加密和解密的方法,感興趣的可以學習一下
    2022-05-05
  • golang解析json數(shù)據(jù)的4種方法總結

    golang解析json數(shù)據(jù)的4種方法總結

    在日常工作中每一名開發(fā)者,不管是前端還是后端,都經常使用 JSON,下面這篇文章主要給大家介紹了關于golang解析json數(shù)據(jù)的4種方法,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • go原生庫的中bytes.Buffer用法

    go原生庫的中bytes.Buffer用法

    這篇文章主要介紹了go原生庫的中bytes.Buffer用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 詳解如何在Go服務中做鏈路追蹤

    詳解如何在Go服務中做鏈路追蹤

    使用 Go 語言開發(fā)微服務的時候,需要追蹤每一個請求的訪問鏈路,本文主要介紹了如何在Go 服務中做鏈路追蹤,感興趣的可以了解一下
    2021-09-09
  • Golang的鎖機制與使用技巧小結

    Golang的鎖機制與使用技巧小結

    本文主要介紹了Golang的鎖機制與使用技巧小結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-06-06
  • go語言實現(xiàn)通過FTP庫自動上傳web日志

    go語言實現(xiàn)通過FTP庫自動上傳web日志

    這篇文章主要介紹了go語言實現(xiàn)通過FTP庫自動上傳web日志,非常簡單實用,需要的小伙伴快來參考下吧。
    2015-03-03
  • 使用Golang的Context管理上下文的方法

    使用Golang的Context管理上下文的方法

    這篇文章主要介紹了使用Golang的Context管理上下文的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09

最新評論