go 1.18 泛型初體驗
go 1.18 泛型初體驗
go.1.18beta 版釋出,眾所周知這個 go.1.18 版本會預設啟用 go 泛型。這個版本也號稱 go 最大的版本改動。
初識 golang 的泛型
我們寫一個 demo 來看看 go 的泛型是長啥樣
package main
import (
"fmt"
)
type OrderTypes interface {
~int | ~float32 | ~string
}
func max[T OrderTypes](x, y T) T {
if x > y {
return x
}
return y
}
func main() {
fmt.Println(max(1, 11), max("abc", "eff"))
}
ok run 一下程式碼
$ go run main.go
11 eff
~int | ~float32 | ~string
我們看到了新的語法,~
是新的操作符,主要用來做型別約束使用, ~int
代表型別約束為int
型別,~int | ~float32 | ~string
則代表約束為 int
或者 float32
或者 string
。上面額例子中,這三個型別剛好是可以比較的能進行 ">" 操作的。
當然上面的程式碼是演示用的,在真正的專案中我們應該使用標準constraints
提供的Ordered
來做約束。
import (
"constraints"
)
func max[T constraints.Ordered](x, y T) T {
if x > y {
return x
}
return y
}
constraints
標準庫定義了一下常用的型別約束,如Ordered
,Signed
,Unsigned
,Integer
,Float
。
提高生產力的泛型
我們通過下面的例子來看看泛型,如何提高我們的生產力。我們將為所有slice
型別新增三件套map
,reduce
,filter
func Map[Elem1, Elem2 any](s []Elem1, f func(Elem1) Elem2) []Elem2 {
r := make([]Elem2, len(s))
for i, v := range s {
r[i] = f(v)
}
return r
}
func Reduce[Elem1, Elem2 any](s []Elem1, initializer Elem2, f func(Elem2, Elem1) Elem2) Elem2 {
r := initializer
for _, v := range s {
r = f(r, v)
}
return r
}
func Filter[Elem any](s []Elem, f func(Elem) bool) []Elem {
var r []Elem
for _, v := range s {
if f(v) {
r = append(r, v)
}
}
return r
}
func Silce() {
sliceA := []int{3, 99, 31, 63}
//通過sliceA 生成sliceB
sliceB := Map(sliceA, func(e int) float32 {
return float32(e) + 1.3
})
fmt.Println(sliceB)
//找最大值
max := Reduce(sliceB, 0.0, func(a, b float32) float32 {
if a > b {
return a
}
return b
})
fmt.Println(max)
//過濾sliceA中大於30的組成新的slice
sliceC := Filter(sliceA, func(e int) bool {
if e > 30 {
return true
}
return false
})
fmt.Println(sliceC)
}
func main() {
Silce()
}
$ go run main.go
[4.3 100.3 32.3 64.3]
100.3
[99 31 63]
帶泛型的struct
接下來我們看一下帶泛型的struct
//定義的時候需要加約束
type Student[T constraints.Unsigned] struct {
Age T
}
//後續struct方法編寫的時候 約束就不能寫了
func (s *Student[T]) GetAge() T {
return s.Age
}
我們初始化帶泛型的結構圖
age := uint(3)
s := &Student[uint]{Age: age}
fmt.Println(s.GetAge()) //3
s1 := &Student[uint16]{Age: uint16(age)}
fmt.Println(s1.GetAge()) //3
總結
go 的泛型目前還沒有官方推薦的最佳實踐,標準庫的程式碼也基本沒改成泛型。但總歸走出支援泛型這一步,後續豐富標準庫應該是後面版本的事情了。再看go2程式碼的時候發現一個有意思的東西--orderedmap
。感興趣的同學可以去看看。
更多原創文章乾貨分享,請關注公眾號
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Go 1.18泛型的侷限性初探Go泛型
- 預計在 Go 1.18 中內建泛型Go泛型
- go1.18泛型的簡單嘗試Go泛型
- 支援泛型的Go語言1.18釋出泛型Go
- Go 1.18 泛型全面講解:一篇講清泛型的全部Go泛型
- Go 1.18 泛型的一些技巧和困擾Go泛型
- go modules 初體驗Go
- Go 泛型Go泛型
- Go 泛型之泛型約束Go泛型
- Go初體驗|基礎Go
- ebpf-go 初體驗eBPFGo
- Go 創始人 Rob Pike 反對在 Go 1.18 標準庫中引入泛型支援:建議不要改動 Go 1.18 中的標準庫Go泛型
- go泛型教程Go泛型
- Go初體驗|Mac上安裝GoGoMac
- go語言的初體驗Go
- 終於!Go 1.18 將支援泛型,來聽聽Go 核心技術團隊 Russ Cox怎麼說Go泛型
- 泛型的初運用泛型
- go語言學習初體驗Go
- 泛型最佳實踐:Go泛型設計者教你如何用泛型泛型Go
- Go 官方出品泛型教程:如何開始使用泛型Go泛型
- Java & Go 泛型對比JavaGo泛型
- Go泛型基礎使用Go泛型
- Go 1.17 泛型嚐鮮Go泛型
- 被動型IAST工具DongTai初體驗ASTAI
- go需要泛型的場景Go泛型
- Go 需要泛型的場景Go泛型
- Go 快速指南:go1.18 特性Go
- Go Internals: Go 反射 vs Java 泛型 vs cpp 模板Go反射Java泛型
- Go 1.18 正式釋出!Go
- 一位 Rust 開發者的 Go 初體驗RustGo
- Go中泛型和反射比較指南Go泛型反射
- Go泛型草案設計簡明指南Go泛型
- ReactNative初體驗React
- OpenCV 初體驗OpenCV
- http初體驗HTTP
- Flutter初體驗Flutter
- Nuxt 初體驗UX
- jQuery初體驗jQuery