Go 1.17 beta版新特性。
1. 切片可以显式地转换成数组切片了
如果切片的长度小于目标数组的长度,一个恐慌将产生。一个例子:
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
}
2. sync/atomic.Value类型增加了两个方法:Swap和CompareAndSwap
下面是一个使用了这两个方法的例子:
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}}
}
3. unsafe包增加了两个函数:
func Add(ptr Pointer, len IntegerType Pointer。 此函数对一个(非安全)指针添加一个偏移量。
func Slice(ptr *ArbitraryType, len IntegerType []ArbitraryType。 此函数用来从一个任意(安全)指针派生出一个指定长度的切片。
下面是使用了这两个函数的一个例子:
package main
import (
"fmt"
"unsafe"
func main( {
a := [16]int{3: 3, 9: 9, 11: 11}
fmt.Println(a // 使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
}