2023年8月8日晚上 11 点 30 多,Go语言发布了最新版本Go1.21.0,它带来了一些语言和工具的变化:
升级内容
新增内置函数
min和max内置函数
Go1.21.0增加了两个新的内置函数min和max,用来对任意可比较的有序类型进行最小值或最大值的操作。min和max函数可以接受一个或多个参数,并返回其中的最小值或最大值。如果参数是浮点数并且包含NaN,min和max函数会返回NaN。
clear预定义函数
Go1.21.0增加了一个clear预定义函数用来做切片和map的clear操作。对于切片,clear函数会将所有元素设置为零值,但保持切片的长度和容量不变。对于map,clear函数会删除所有键值对,得到一个空map。
改变panic(nil)语义
Go1.21.0改变了panic(nil)的语义,使得recover函数在捕获到panic(nil)时不再返回nil,而是返回一个特定的错误类型PanicNilError。这样可以避免开发者误以为没有发生panic,而继续执行正常逻辑。
循环变量捕获
在未来版本中,开发团队计划解决 Go 编程中最常见的问题之一:循环变量捕获 (loop variable capture)。Go 1.21 附带了此功能的预览版,目前可以使用环境变量在代码中启用该功能。
新增标准库
log/slog 包
用于结构化日志记录
slices 包
增用于对任何元素类型的切片进行常见操作,这个包比 sort 包更快、更符合人体工程学
maps 包
用于对任何类型 key-value 进行常见操作
cmp 包
用于比较有序值 (ordered values)
优化性能
改进工具链
配置文件引导优化 (PGO) 功能正式 GA。
在 1.20 中处于预览阶段的启用配置文件引导优化 (PGO) 功能现已正式 GA。如果主软件包目录中存在名为 default.pgo 的文件,go 命令将使用它来启用 PGO 构建。
- Go 编译器本身已经在 1.21 中启用 PGO 进行了重建,因此它构建 Go 程序的速度提高了 2-4%,具体取决于主机架构
- 由于垃圾收集器的调整,某些应用程序的尾部延迟可能会减少高达 40%
- 现在使用 runtime/trace 收集跟踪在 amd64 和 arm64 上产生的 CPU 开销要小得多
支持 WASI
Go 1.21 已实验性支持 WebAssembly System Interface (WASI), Preview 1 (GOOS=wasip1,GOARCH=wasm)。
为了方便编写更通用的 WebAssembly (WASM) 代码,编译器还支持从 WASM 主机导入函数的新指令: go:wasmimport 。
下载地址
Windows版本
https://golang.google.cn/dl/go1.21.0.windows-amd64.msi
Linux版本
https://golang.google.cn/dl/go1.21.0.linux-amd64.tar.gz
Mac Os ARM64版本
https://golang.google.cn/dl/go1.21.0.darwin-arm64.pkg
Mac Os x86-64版本
https://golang.google.cn/dl/go1.21.0.darwin-amd64.pkg
还有一个网址,也能下载到所有版本,速度比较慢:
All releases - The Go Programming Language
安装流程
Windows版
打开windows版安装程序,如下图:
一路点Next直到安装完成,如果之前安装过旧版本,安装程序会让你删除旧版本的,但不用中途退出只多点一次Yes。安装结束后,进入cmd 命令提示符窗口查看版本号。
如下图,键入: go version
Linux版
1. 删除旧版本
hann@HannYang:~$ go version
go version go1.13.8 linux/amd64
hann@HannYang:~$ which go
/usr/bin/go
hann@HannYang:~$ sudo rm -rf /usr/bin/go
[sudo] password for hann:
hann@HannYang:~$ go version
-bash: /usr/bin/go: No such file or directory
2. 下载新版本
hann@HannYang:~$ sudo wget https://golang.google.cn/dl/go1.21.0.linux-amd64.tar.gz
3. 解压到安装目录
hann@HannYang:/$ ls go1.21.0.linux-amd64.tar.gz
go1.21.0.linux-amd64.tar.gz
hann@HannYang:/$ sudo tar -C /usr/local -xzf go1.21.0.linux-amd64.tar.gz
hann@HannYang:/$ ls /usr/local
bin etc games go include lib man sbin share src
4. 添加路径
hann@HannYang:/$ sudo vi /etc/profile
在最后添加以下命令行,:wq 保存退出。
export PATH=$PATH:/usr/local/go/bin
5. 生效配置
hann@HannYang:/$ sudo source /etc/profile
6. 安装成功
hann@HannYang:/$ go version
go version go1.21.0 linux/amd64
注:因涉及读写权限,上面安装用的几个命令都用 sudo command 形式执行。
darwin版
没有mac pc,略
测试新函数
max()和min()
终于有 max()和min() 函数了,之前一直奇怪Go为何这么简单的函数都没有,还要自己写。
测试代码:
package main import "fmt" func main() { a := max(6, 1, 3, 2, 3, 18) b := min(6, 1, 3, 2, 3, 18) fmt.Println(a, b) //除了比较整数、浮点数,还能比较字符串 cMax := max("apple", "banana", "cherry") cMin := min("apple", "banana", "cherry") fmt.Println(cMax, cMin) }
输出:
18 1
cherry apple
而没升级之前的旧版本,就算是比较2个整数要带上自定义函数,如下:
func max(a, b int) int { if a > b { return a } return b } func min(a, b int) int { if a < b { return a } return b }
clear()
格式: clear[T ~[]Type | ~map[Type]Type1](t T)
- 对于 map,会删除所有条目(包含 NaN),将会变成一个空 map。len 属性的值会改变,值为 0 。
- 对于 slice,会将 slice 或 array 长度内的所有元素设置为相应元素类型的零值。len 属性的值不会改变。
- 对于泛型的类型参数(type parameter):类型参数的类型集必须只包含 map、slices 或指向数组的指针的类型,clear 函数将会执行实际类型参数所对应的 clear 操作。
测试代码:
package main import "fmt" func main() { m := map[string]string{ "fruit": "apple", "vegetable": "eggplant", "meat": "pork", } fmt.Printf("m1: %v, len: %d\n", m, len(m)) clear(m) fmt.Printf("m2: %v, len: %d\n", m, len(m)) s := make([]string, 4) s[0] = "水" s[1] = "果" s[2] = "蔬" s[3] = "菜" fmt.Printf("s1: %v, len: %d, cap:%d\n", s, len(s), cap(s)) clear(s) fmt.Printf("s2: %v, len: %d, cap:%d\n", s, len(s), cap(s)) }
输出:
m1: map[fruit:apple meat:pork vegetable:eggplant], len: 3
m2: map[], len: 0
s1: [水 果 蔬 菜], len: 4, cap:4
s2: [ ], len: 4, cap:4
还有其它升级内容,抽空再慢慢体会......
完。