go 1.17简介
最新的Go版本1.17在Go 1.16 6个月后发布。它的大多数更改都是在工具链、运行时和库的实现中进行的。和往常一样,这个版本保持了Go 1对兼容性的承诺。我们希望几乎所有的Go程序都能像以前一样继续编译和运行
语言变更
- 切片可以显式地转换成数组指针了。如果切片的长度小于目标数组的长度,一个恐慌将产生。一个例子: ```go package main
type S []int type A [2]int type P *A
func main() { var x = make([]int, 3, 5) var = (*[3]int)(x) // okay var = ([2]int)(x) // okay var _ = (A)(x) // okay var _ = P(x) // okay
var y = S(x)
var _ = (*[3]int)(y) // okay
var _ = (*[2]int)(y) // okay
var _ = (*A)(y) // okay
var _ = P(y) // okay
var _ = (*[4]int)(x) // panic
}
<br />2. sync/atomic.Value类型增加了两个方法:Swap和CompareAndSwap。下面是一个使用了这两个方法的例子:
```go
package main
import (
"fmt"
"sync/atomic"
)
func main() {
type T struct {a, b, c int}
var x = T{1, 2, 3}
var y = T{4, 5, 6}
var z = T{7, 8, 9}
var v atomic.Value
v.Store(x)
fmt.Println(v) // {{1 2 3}}
old := v.Swap(y)
fmt.Println(v) // {{4 5 6}}
fmt.Println(old.(T)) // {1 2 3}
swapped := v.CompareAndSwap(x, z)
fmt.Println(swapped, v) // false {{4 5 6}}
swapped = v.CompareAndSwap(y, z)
fmt.Println(swapped, v) // true {{7 8 9}}
}
- unsafe包增加了两个函数:
- func Add(ptr Pointer, len IntegerType) Pointer。 此函数对一个(非安全)指针添加一个偏移量。
- func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType。 此函数用来从一个任意(安全)指针派生出一个指定长度的切片。 ```go package main
import ( “fmt” “unsafe” )
func main() { a := [16]int{3: 3, 9: 9, 11: 11} fmt.Println(a) eleSize := int(unsafe.Sizeof(a[0])) p9 := &a[9] up9 := unsafe.Pointer(p9) p3 := (int)(unsafe.Add(up9, -6 eleSize)) fmt.Println(*p3) // 3
s := unsafe.Slice(p9, 5)[:3] fmt.Println(s) // [9 0 11] fmt.Println(len(s), cap(s)) // 3 5
// 下面是两个不正确的调用。因为它们 // 的返回结果引用了未知的内存块。 = unsafe.Add(up9, 7 * eleSize) = unsafe.Slice(p9, 8) } ```
编译器
Go 1.17实现了一种通过寄存器而不是堆栈传递函数参数和结果的新方法,这项改进使得Go程序的性能得以提高约5%,amd64平台的二进制文件大小减少2%,官方提到,未来版本还会支持更多的平台。另外,Go 1.17还增加对Windows上64位元Arm架构的支持,因此Go程序可以在更多的设备上原生运行。