大家好,我是煎鱼。
在 2022 年 3 月,Go1.18 终于发布。在该版本中,包含了 Go1.17 起就已存在的泛型,并于此版本正式发布泛型特性。
这是一个备受关注和争议的新特性。在 reddit 甚至有网友放出了这张图:
曾经在 Go1.18 时,Go 语言之父 @Rob Pike 冒了个泡,掌了舵,让不要这么急把泛型重写进标准库。怕太着急,对泛型不熟会翻车。
如下图:
在经历了一年半的等待后,最近 Go slices 和 maps 的泛型库,终于被合并进 master 分支了。这意味着在 Go1.21 起,将会有泛型库进入官方标准库。
这相当于是个比较有标志性的节点了。
以下我们先看看一个简单的泛型 Demo,再看看具体的 slices 和 maps 的泛型标准库库的 API 和使用方式。
以下是社区提供的一个泛型快速 Demo,可以跟着思考运行一下,看看自己泛型的基本使用掌握的如何。
代码如下:
package main
import "fmt"
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
}
type List[T any] struct {
head, tail *element[T]
}
type element[T any] struct {
next *element[T]
val T
}
func (lst *List[T]) Push(v T) {
if lst.tail == nil {
lst.head = &element[T]{val: v}
lst.tail = lst.head
} else {
lst.tail.next = &element[T]{val: v}
lst.tail = lst.tail.next
}
}
func (lst *List[T]) GetAll() []T {
var elems []T
for e := lst.head; e != nil; e = e.next {
elems = append(elems, e.val)
}
return elems
}
func main() {
var m = map[int]string{1: "2", 2: "4", 4: "8"}
fmt.Println("keys:", MapKeys(m))
_ = MapKeys[int, string](m)
lst := List[int]{}
lst.Push(10)
lst.Push(13)
lst.Push(23)
fmt.Println("list:", lst.GetAll())
}
输出结果:
keys: [4 1 2]
list: [10 13 23]
以下给大家介绍泛型 slices 库的 API 和对应的用法。如果有看源码的兴趣,可以查看 src/slices/slices.go 文件。
其包含如下方法:
func BinarySearch[E constraints.Ordered](x []E, target E) (int, bool)
func BinarySearchFunc[E, T any](x []E, target T, cmp func(E, T) int) (int, bool)
func Clip[S ~[]E, E any](s S) S
func Clone[S ~[]E, E any](s S) S
func Compact[S ~[]E, E comparable](s S) S
func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S
func Compare[E constraints.Ordered](s1, s2 []E) int
func CompareFunc[E1, E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) int) int
s[:len(s):len(s)]
。func Contains[E comparable](s []E, v E) bool
func ContainsFunc[E any](s []E, f func(E) bool) bool
func Delete[S ~[]E, E any](s S, i, j int) S
s[i:j]
,返回被修改(删除元素)后的切片。func Equal[E comparable](s1, s2 []E) bool
func EqualFunc[E1, E2 any](s1 []E1, s2 []E2, eq func(E1, E2) bool) bool
func Grow[S ~[]E, E any](s S, n int) S
func Index[E comparable](s []E, v E) int
func IndexFunc[E any](s []E, f func(E) bool) int
func Insert[S ~[]E, E any](s S, i int, v ...E) S
func Replace[S ~[]E, E any](s S, i, j int, v ...E) S
func IsSorted[E constraints.Ordered](x []E) bool
func IsSortedFunc[E any](x []E, less func(a, b E) bool) bool
func Sort[E constraints.Ordered](x []E)
func SortFunc[E any](x []E, less func(a, b E) bool)
func SortStableFunc[E any](x []E, less func(a, b E) bool)
以下给大家介绍泛型库的 API 和对应的用法。如果有看源码的兴趣,可以查看 src/maps/maps.go 文件。
其包含如下方法:
func Keys[M ~map[K]V, K comparable, V any](m M) []K
func Values[M ~map[K]V, K comparable, V any](m M) []V
func Equal[M1, M2 ~map[K]V, K, V comparable](m1 M1, m2 M2) bool
func EqualFunc[M1 ~map[K]V1, M2 ~map[K]V2, K comparable, V1, V2 any](m1 M1, m2 M2, eq func(V1, V2) bool) bool
func DeleteFunc[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool)
func Clear[M ~map[K]V, K comparable, V any](m M)
func Clone[M ~map[K]V, K comparable, V any](m M) M
func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2)
Go 语言加不加泛型,怎么加泛型。吵了十多年,才把泛型这个新特性纳入进来。又花了一年半的时间,才把标准库最常见用的 slices、maps 泛型再逐步纳入进来。
虽然听起来一切都是那么的让人激动。但你细数一下时间,其实是比较久的。等 Go 官方库都能够叱咤泛型,可能还需要相当一段的时间。
你在你的 Go 项目代码中用上了吗?
关注和加煎鱼微信,
一手消息和知识,拉你进技术交流群👇
你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路。
日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!