細(xì)細(xì)探究Go 泛型generic設(shè)計(jì)
Go 泛型
的設(shè)計(jì)融入了現(xiàn)代語(yǔ)言的風(fēng)格,比如類型限制(type constraint),我們?cè)?TypeScript 和 Python 也能看到這個(gè)特性。
今天我就好好品味一下這個(gè)泛型設(shè)計(jì),和老版本的 Go 做一個(gè)對(duì)比,并且加入類型限制的例子。
demo
直接進(jìn)入正題:
package main
import "fmt"
// 代碼中首先定義了一個(gè)接口類型 `Number`,
// 它包含了兩個(gè)類型:`int64` 和 `float64`。
// 這個(gè)接口類型可以被用來(lái)限制泛型函數(shù)的類型參數(shù)范圍。
type Number interface {
int64 | float64
}
// 定義了兩個(gè)非泛型函數(shù) `SumInts` 和 `SumFloats`,
// 它們分別用于計(jì)算 `int64` 類型和 `float64` 類型的 map 中所有值的總和。
// SumInts adds together the values of m.
func SumInts(m map[string]int64) int64 {
var s int64
for _, v := range m {
s += v
}
return s
}
// SumFloats adds together the values of m.
func SumFloats(m map[string]float64) float64 {
var s float64
for _, v := range m {
s += v
}
return s
}
// 定義了一個(gè)泛型函數(shù) `SumIntsOrFloats`,它接受一個(gè)類型為 `map[K]V` 的 map,并返回這個(gè) map 中所有值的總和。
// 這個(gè)函數(shù)使用了兩個(gè)類型參數(shù) `K` 和 `V`,其中 `V` 的類型可以是 `int64` 或 `float64` 中的一個(gè)。
// 函數(shù)中使用了 `for range` 語(yǔ)句來(lái)遍歷 map 中的值并計(jì)算它們的總和,最終返回這個(gè)總和。
// SumIntsOrFloats sums the values of map m. It supports both floats and integers
// as map values.
func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
// `SumNumbers`,它的類型參數(shù) `V` 必須實(shí)現(xiàn) `Number` 接口類型。
// 這個(gè)函數(shù)和 `SumIntsOrFloats` 函數(shù)類似,不同之處在于它使用了 `Number` 接口類型來(lái)限制 `V` 的取值范圍
// 只有實(shí)現(xiàn)了 `Number` 接口類型的類型才能作為 `V` 的值類型。
// SumNumbers sums the values of map m. Its supports both integers
// and floats as map values.
func SumNumbers[K comparable, V Number](m map[K]V) V {
var s V
for _, v := range m {
s += v
}
return s
}
func main() {
// Initialize a map for the integer values
ints := map[string]int64{
"first": 34,
"second": 12,
}
// Initialize a map for the float values
floats := map[string]float64{
"first": 35.98,
"second": 26.99,
}
fmt.Printf("Non-Generic Sums: %v and %v\n",
SumInts(ints),
SumFloats(floats))
fmt.Printf("Generic Sums: %v and %v\n",
SumIntsOrFloats[string, int64](ints),
SumIntsOrFloats[string, float64](floats))
fmt.Printf("Generic Sums, type parameters inferred: %v and %v\n",
SumIntsOrFloats(ints),
SumIntsOrFloats(floats))
fmt.Printf("Generic Sums with Constraint: %v and %v\n",
SumNumbers(ints),
SumNumbers(floats))
}
在 main 函數(shù)中,代碼初始化了兩個(gè) map,分別用于存儲(chǔ) int64 類型和 float64 類型的值。接著,代碼使用非泛型的 SumInts 和 SumFloats 函數(shù)來(lái)計(jì)算這兩個(gè) map 中所有值的總和,并打印出結(jié)果。然后,代碼使用泛型的 SumIntsOrFloats 函數(shù)來(lái)計(jì)算這兩個(gè) map 中所有值的總和,并打印出結(jié)果。最后,代碼使用帶有類型約束的泛型函數(shù) SumNumbers 來(lái)計(jì)算這兩個(gè) map 中所有值的總和,并打印出結(jié)果。
這段代碼演示了 Go 語(yǔ)言中泛型的應(yīng)用,通過(guò)這個(gè)例子,我們可以更好地理解 Go 語(yǔ)言中的泛型功能。
如果不用泛型,我們可能要進(jìn)行多次復(fù)制粘貼,代碼不易維護(hù)。
如果不用類型限制,一旦加入一個(gè)類型,原有模塊也不易維護(hù)。
我們用類型限制,也就是所謂的 type contract 達(dá)成一種共識(shí),大家一眼便知,這個(gè)和 interface 代表的接口特性是一個(gè)道理。
以上就是細(xì)細(xì)探究Go 泛型generic設(shè)計(jì)的詳細(xì)內(nèi)容,更多關(guān)于Go 泛型generic設(shè)計(jì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
GPT回答:go語(yǔ)言和C語(yǔ)言切片對(duì)比
這篇文章主要為大家介紹了GPT回答:go語(yǔ)言和C語(yǔ)言切片對(duì)比,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
go開(kāi)發(fā)中引用靜態(tài)庫(kù).a文件的方法
這篇文章主要介紹了go開(kāi)發(fā)中引用靜態(tài)庫(kù).a文件的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
go語(yǔ)言的panic和recover函數(shù)用法實(shí)例
今天小編就為大家分享一篇關(guān)于go語(yǔ)言的panic和recover函數(shù)用法實(shí)例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04
Go語(yǔ)言中validation庫(kù)不能校驗(yàn)零值問(wèn)題的解決方法
在使用 Gin 框架的時(shí)候,前后端傳遞數(shù)據(jù)的時(shí)候,比如使用 JSON 格式,通常會(huì)使用 ShouldBindJSON 去用結(jié)構(gòu)體打 tag 綁定前端傳來(lái)的 JSON 格式數(shù)據(jù),本文給大家介紹了Go語(yǔ)言中validation庫(kù)不能校驗(yàn)零值問(wèn)題的解決方法,需要的朋友可以參考下2024-08-08
基于微服務(wù)框架go-micro開(kāi)發(fā)gRPC應(yīng)用程序
這篇文章介紹了基于微服務(wù)框架go-micro開(kāi)發(fā)gRPC應(yīng)用程序的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07

