go 1.17简介

最新的Go版本1.17在Go 1.16 6个月后发布。它的大多数更改都是在工具链、运行时和库的实现中进行的。和往常一样,这个版本保持了Go 1对兼容性的承诺。我们希望几乎所有的Go程序都能像以前一样继续编译和运行

语言变更

  1. 切片可以显式地转换成数组指针了。如果切片的长度小于目标数组的长度,一个恐慌将产生。一个例子: ```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

  1. var y = S(x)
  2. var _ = (*[3]int)(y) // okay
  3. var _ = (*[2]int)(y) // okay
  4. var _ = (*A)(y) // okay
  5. var _ = P(y) // okay
  6. var _ = (*[4]int)(x) // panic

}

  1. <br />2. sync/atomic.Value类型增加了两个方法:Swap和CompareAndSwap。下面是一个使用了这两个方法的例子:
  2. ```go
  3. package main
  4. import (
  5. "fmt"
  6. "sync/atomic"
  7. )
  8. func main() {
  9. type T struct {a, b, c int}
  10. var x = T{1, 2, 3}
  11. var y = T{4, 5, 6}
  12. var z = T{7, 8, 9}
  13. var v atomic.Value
  14. v.Store(x)
  15. fmt.Println(v) // {{1 2 3}}
  16. old := v.Swap(y)
  17. fmt.Println(v) // {{4 5 6}}
  18. fmt.Println(old.(T)) // {1 2 3}
  19. swapped := v.CompareAndSwap(x, z)
  20. fmt.Println(swapped, v) // false {{4 5 6}}
  21. swapped = v.CompareAndSwap(y, z)
  22. fmt.Println(swapped, v) // true {{7 8 9}}
  23. }
  1. 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程序可以在更多的设备上原生运行。