随着 Go 语言的不断迭代,新版本带来了许多实用的标准库函数,使得代码更加简洁、可读性更强。本篇文章主要介绍 Go 1.21+ 版本中的一些新特性,涵盖 可变类型比较、slice 最大值与最小值、map 转换为 slice 以及 map 合并 等常见场景,展示如何利用新特性优化代
在 Go 语言中,比较两个数的大小通常使用 if
语句,但 Go 1.21 之后引入了新的内置函数,比如 max()
和 min()
。
旧写法
oldFunc := func(a, b int) (int, int) {
maxValue := a
if a < b {
maxValue = b
}
minValue := a
if a > b {
minValue = b
}
return maxValue, minValue
}
新写法
newFunc := func(i, j int) (int, int) {
maxValue := max(i, j)
minValue := min(i, j)
return maxValue, minValue
}
注意点:
如果我们看下源码:
func max[T cmp.Ordered](x T, y ...T) T
不难发现这个函数的参数貌似支持一个数字和一个数组一起进行比较,然后我们试一下:
newFunc := func(i int, l ...int) (int, int) {
fmt.Println(max(i, l...))
// ...
}
就会发现编译的时候会报错:invalid use of ... with built-in max
。这是为什么呢?
因为在Go语言中,...
是用于可变参数函数的语法糖。当你在函数调用中使用 ...
时,它会将一个切片展开为多个参数。然而,Go语言的内置函数 max 和 min 并不支持可变参数,因此你不能在调用这些函数时使用 ...
。
在旧版本中,需要手动遍历 slice 来求最大/最小值。而在 Go 1.21+ 中,slices.Max
和 slices.Min
让这件事变得更简单。
旧写法
oldFunc := func(s []int) (int, int) {
maxValue := s[0]
for i := 1; i < len(s); i++ {
maxValue = max(maxValue, s[i])
}
minValue := s[0]
for i := 1; i < len(s); i++ {
minValue = min(minValue, s[i])
}
return maxValue, minValue
}
新写法
import "slices"
newFunc := func(s []int) (int, int) {
maxValue := slices.Max(s)
minValue := slices.Min(s)
return maxValue, minValue
}
在开发过程中,我们经常需要将 map 的 key 或 value 提取为 slice。Go 1.21 之前,需要手动遍历 map,而新版本提供了 maps.Keys
和 maps.Values
。
旧写法
oldFunc := func(m map[string]string) ([]string, []string) {
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}
values := make([]string, 0, len(m))
for _, value := range m {
values = append(values, value)
}
return keys, values
}
新写法
import "maps"
newFunc := func(m map[string]string) ([]string, []string) {
keys := slices.Collect(maps.Keys(m))
values := slices.Collect(maps.Values(m))
return keys, values
}
Go 1.21 之前,map 合并需要手写循环,而新版本引入了 maps.Insert
,让 map 合并变得更加简单。
旧写法
oldFunc := func(m1, m2 map[string]int) map[string]int {
dst := map[string]int{"c": 3, "d": 4}
for k, v := range m1 {
dst[k] = v
}
return dst
}
新写法
newFunc := func(m1, m2 map[string]int) map[string]int {
dst := map[string]int{"c": 3, "d": 4}
maps.Insert(dst, maps.All(m1))
return dst
}
本篇结束~