Go 1.20 发布了
2023-02-11 Golang
前言
这几天所有的热度都集中到了 ChatGPT
,不过我对这件事情没有什么兴趣,原本计划换换脑,看一下 Docker 基础相关技术,恰巧这时 兔兔大佬 发来了灵魂拷问 …
果然,我的驱动力主要来自外界,于是乎,就有了官网文章的这篇翻译版 (官方文章中不重要的细节忽略了,想一览无余的读者参考附录链接 1)。
PGO
Go 1.20 发布了 配置文件引导优化 (PGO)
的预览版,使编译器能够根据运行时配置文件信息,执行应用程序和工作负载的特定性优化。
提供要构建的配置文件,使编译器能够将应用程序的速度提高大约 3–4%
,官方鼓励开发者尝试一下整个特性,但是可能存在一些未知的小问题。
具体可参考 Profile-guided optimization。
语言变化
- 切片可以直接转换为数组
unsafe
包中添加了Slice
,SliceData
,String
,StringData
函数
切片转数组示例
package main
import "fmt"
func main() {
sli := []int{1, 2, 3, 4, 5}
arr := [5]int(sli)
fmt.Println(arr)
}
// 输出如下
// [1 2 3 4 5]
unsafe 包中新增函数原型
package unsafe
// Slice 根据指针参数和长度参数构造一个切片并返回
// 修改切片元素值会影响底层的数组元素值
func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
// SliceData 返回参数切片的指针
func SliceData(slice []ArbitraryType) *ArbitraryType
// String 根据指针参数和长度参数构造一个字符串并返回
// 修改参数指向的值会同时修改字符串的值
func String(ptr *byte, len IntegerType) string
// StringData 返回参数字符串底层的字节数组指针
func StringData(str string) *byte
下面是两个小例子,分别使用到了 Slice
函数和 String
函数。
根据数组生成切片
package main
import (
"fmt"
"unsafe"
)
func main() {
arr := [5]int{1, 2, 3, 4, 5}
// 注意: 这里是传递首个元素的指针,而非数组的指针
sli := unsafe.Slice(&arr[0], 3)
fmt.Printf("slice = %+v, len = %d\n", sli, len(sli))
// 修改切片元素的值会影响底层的数组
for i := range sli {
sli[i] *= 100
}
fmt.Printf("slice = %+v, len = %d\n", sli, len(sli))
// 此时数组的元素值已经变化
fmt.Printf("array = %+v, len = %d\n", arr, len(arr))
}
// 运行输出如下
// slice = [1 2 3], len = 3
// slice = [100 200 300], len = 3
// array = [100 200 300 4 5], len = 5
根据切片生成字符串
package main
import (
"fmt"
"unsafe"
)
func main() {
bs := []byte{'h', 'e', 'l', 'l', 'o'}
// 注意: 这里是传递首个元素的指针,而非切片的指针
str := unsafe.String(&bs[0], 2)
fmt.Printf("str = %s, len = %d\n", str, len(str))
// 修改参数指向的值会同时修改字符串的值
bs[1] = 'i'
// 此时字符串的值已经变化
fmt.Printf("str = %s, len = %d\n", str, len(str))
fmt.Printf("bs = %s, len = %d\n", bs, len(str))
}
// 运行输出如下
// str = he, len = 2
// str = hi, len = 2
// bs = hillo, len = 2
工具改进
cover
工具可以收集整个程序的覆盖率,不仅仅是单元测试go build
、go install
和其他与构建相关的命令可以接收一个-pgo
标志,启用配置文件引导优化,以及一个-cover
标志,用于整个程序覆盖率分析go test -json
的实现已得到改进,可以处理复杂多样的Stdout
输出vet
在并行运行的测试中可能会发生更多循环变量引用错误- 没有
C 工具链
的系统上默认禁用CGO
标准库增强
- 新方法
errors.Join
返回一个错误列表,如果错误类型实现了Unwrap() []error
,则可以再次获得错误列表 - 新增了几个
时间转换格式常量
,不用再死记硬背蛋疼的2006-01-02 15:04:05
了 :-) - 新包
crypto/ecdh
支持通过 NIST 曲线和 Curve25519 椭圆曲线 Diffie-Hellman 密钥交换 - 新类型
http.ResponseController
访问 http.ResponseWriter 接口未处理的扩展请求 httputil.ReverseProxy
包含一个新的 Rewrite 钩子函数,取代了之前的 Director 钩子- 新方法
context.WithCancelCause
提供了一种方法来取消具有给定错误的上下文 os/exec.Cmd
结构体中的新字段 Cancel 和 WaitDelay, 指定 Cmd 在其关联的 Context 被取消或其进程退出时的回调
errors.Join 示例
package main
import (
"errors"
"fmt"
)
func main() {
err1 := errors.New("error1")
err2 := errors.New("error2")
err3 := errors.New("error3")
err := errors.Join(err1, err2, err3)
fmt.Println(err)
}
时间转换格式常量
package time
const (
DateTime = "2006-01-02 15:04:05"
DateOnly = "2006-01-02"
TimeOnly = "15:04:05"
)
性能提升
- 编译器和 GC 的优化减少了内存开销,并将 CPU 性能整体提高了
2%
- 针对编译时间进行了优化,提升了
10%
。使得构建速度与 Go 1.17 保持一致 (恢复到了泛型之前的速度)
从 1.21 版本开始,一些较旧的操作系统将不再受支持:包括 Windows 7、8、Server 2008 和 Server 2012、macOS 10.13 High Sierra 和 10.14 Mojave。
小结
总体来说,基本没有新的功能和特性,在旧的版本基础上,按图索骥即可。