Go1.21 速览:过了一年半,slices、maps 泛型库终于要加入标准库。···

发布时间:2025-05-21 18:52:01 作者:益华网络 来源:undefined 浏览量(2) 点赞(3)
摘要:来源:脑子进煎鱼了 大家好,我是煎鱼。 在 2022 年 3 月,Go1.18 终于发布。在该版本中,包含了 Go1.17 起就已存在的泛型,并于此版本正式发布泛型特性。 这是一个备受关注和争议的新特性。在 reddit 甚至有网友放出了这

来源:脑子进煎鱼了

大家好,我是煎鱼。

在 2022 年 3 月,Go1.18 终于发布。在该版本中,包含了 Go1.17 起就已存在的泛型,并于此版本正式发布泛型特性。

这是一个备受关注和争议的新特性。在 reddit 甚至有网友放出了这张图:

泛型库终于合进 master

曾经在 Go1.18 时,Go 语言之父 @Rob Pike 冒了个泡,掌了舵,让不要这么急把泛型重写进标准库。怕太着急,对泛型不熟会翻车。

如下图:

在经历了一年半的等待后,最近 Go slices 和 maps 的泛型库,终于被合并进 master 分支了。这意味着在 Go1.21 起,将会有泛型库进入官方标准库。

这相当于是个比较有标志性的节点了。

以下我们先看看一个简单的泛型 Demo,再看看具体的 slices 和 maps 的泛型标准库库的 API 和使用方式。

泛型 Demo

以下是社区提供的一个泛型快速 Demo,可以跟着思考运行一下,看看自己泛型的基本使用掌握的如何。

代码如下:

package

 main

import "fmt"func MapKeys[K comparableV any](m map[K]V) []K

 {

    r := make([]K, 0len

(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[intstring

](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

以下给大家介绍泛型 slices 库的 API 和对应的用法。如果有看源码的兴趣,可以查看 src/slices/slices.go 文件。

其包含如下方法:

func BinarySearch[E constraints.Ordered](x []E, target E) (intbool)func BinarySearchFunc[ET any](x []E, target T, cmp func(E, T) int(intbool)BinarySearch:在已排序的切片中搜索目标,并返回找到目标的位置,或者目标在排序顺序中出现的位置;函数会返回一个 bool 值,表示是否真的在切片中找到目标。切片必须按递增顺序排序。BinarySearchFunc:同上类似用法,区别在于可以传自己定义的比较函数。func Clip[S ~[]EE any](s S) Sfunc Clone[S ~[]EE any](s S) Sfunc Compact[S ~[]EE comparable](s S) Sfunc CompactFunc[S ~[]EE any](s S, eq func(E, E) boolSfunc Compare[E constraints.Ordered](s1, s2 []E) intfunc CompareFunc[E1E2 any](s1 []E1, s2 []E2, cmp func(E1, E2) intintClip:从切片中删除未使用的容量,返回 s[:len(s):len(s)]。Clone:拷贝切片的副本,切片元素是使用赋值复制的,是浅拷贝。Compact:将连续运行的相等元素替换为单个副本。类似于 Unix 的 uniq 命令。该函数会直接修改切片的元素,它不会创建新切片。CompactFunc:同上类似用法,区别在于可传自定义函数进行比较。func Contains[E comparable](s []E, v E) boolfunc ContainsFunc[E any](s []E, f func(E) boolboolfunc Delete[S ~[]EE any](s S, i, j int) SContains:在切片中查找所传入的参数是否存在,返回一个 bool 值。ContainsFunc:同上,可传自定义函数。Delete:从切片中删除元素 s[i:j],返回被修改(删除元素)后的切片。func Equal[E comparable](s1, s2 []E) boolfunc EqualFunc[E1E2 any](s1 []E1, s2 []E2, eq func(E1, E2) boolboolfunc Grow[S ~[]EE any](s S, n int) SEqual:检查两个所传入的切片是否相等,需要确保长度相同,所有元素相等。如果长度不同,也是会返回 false。EqualFunc:同上,可传自定义函数。Grow:增加切片的容量,至少增加 n 个元素的空间。如果 n 是负数或者太大,无法分配内存,就会导致产生 panic。func Index[E comparable](s []E, v E) intfunc IndexFunc[E any](s []E, f func(E) boolintfunc Insert[S ~[]EE any](s S, i int, v ...E) Sfunc Replace[S ~[]EE any](s S, i, j int, v ...E) SIndex:返回所需检查元素在切片中第一次出现的索引位置。如果不存在,则返回 -1。IndexFunc:同上,可传自定义函数。Replace:用所传入的参数替换对应的元素,并返回修改后的切片。func IsSorted[E constraints.Ordered](x []E) boolfunc IsSortedFunc[E any](x []E, less func(a, b E) boolboolfunc 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)IsSorted:检查所传入的切片是否以升序排序。IsSortedFunc:同上,可传自定义函数。Sort:按升序对任意有序类型的切片进行排序。SortFunc:同上,可传自定义函数。SortStableFunc:对所传入的切片进行排序,同时保持相等元素的原始顺序,使用较少的元素进行比较。

泛型 maps

以下给大家介绍泛型库的 API 和对应的用法。如果有看源码的兴趣,可以查看 src/maps/maps.go 文件。

其包含如下方法:

func Keys[M ~map[K]VK comparableV any](m M) []Kfunc Values[M ~map[K]VK comparableV any](m M) []Vfunc Equal[M1M2 ~map[K]VKV comparable](m1 M1, m2 M2) boolfunc EqualFunc[M1 ~map[K]V1M2 ~map[K]V2K comparableV1V2 any](m1 M1, m2 M2, eq func(V1, V2) boolboolKeys:返回 map 的键值内容,键值将以不确定的顺序出现。Values:返回 map 的值,值将以不确定的顺序出现。Equal:检查两个 map 是否包含相同的键/值对,内部会使用 == 来比较数值。EqualFunc:EqualFunc与 Equal 方法类似,但使用闭包方法来比较数值,键值仍然用 == 来比较。func DeleteFunc[M ~map[K]VK comparableV any](m M, del func(K, V) bool)func Clear[M ~map[K]VK comparableV any](m M)func Clone[M ~map[K]VK comparableV any](m M) Mfunc Copy[M1 ~map[K]VM2 ~map[K]VK comparableV any](dst M1, src M2)DeleteFunc:删除 map 中闭包方法返回 true 的任何键/值对。Clear:清除从 map 中删除所有条目,使之为空。Clone:返回一个 map 的副本,这是一个浅层克隆,新拷贝出来的的键和值使用普通的赋值来设置。Copy:复制 src 中的所有键/值对,并将其加入 dst。当 src 中的一个键已经存在于 dst 中时,dst 中的值将被与 src 中的键相关的值所覆盖。

总结

Go 语言加不加泛型,怎么加泛型。吵了十多年,才把泛型这个新特性纳入进来。又花了一年半的时间,才把标准库最常见用的 slices、maps 泛型再逐步纳入进来。

虽然听起来一切都是那么的让人激动。但你细数一下时间,其实是比较久的。等 Go 官方库都能够叱咤泛型,可能还需要相当一段的时间。

你在你的 Go 项目代码中用上了吗?

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!