go 1.20中能用到的东西

97 阅读2分钟

代码先行

除了pgo可以利用pprof进行性能优化,其他的主要新用法参考如下代码. 包括数组和切片的转换, 用切片初始化数组, compareable, errors.Join

package main

import (
	"errors"
	"fmt"
	"unsafe"
)

func main() {
	errorsMethod()
}
func errorsMethod() {
	err1 := errors.New("err1")
	err2 := errors.New("err2")
	err := errors.Join(err1, err2)
	fmt.Println(err)
	if errors.Is(err, err1) {
		fmt.Println("err is err1")
	}
	if errors.Is(err, err2) {
		fmt.Println("err is err2")
	}
}

func newMethod() {
	var byteArray = [3]byte{65, 66, 67}
	slice1 := unsafe.Slice(&byteArray[0], 3) //1.用数组的起始指针构造slice
	fmt.Println(slice1)

	str := unsafe.String(&byteArray[0], 3) //2.用数组的起始指针构造string
	fmt.Println(str)

	sliceDataPointer := unsafe.SliceData(slice1) //3.获取slice数据指针
	fmt.Printf("%p,%p\n", &byteArray[0], sliceDataPointer)

	var sl = []int{1, 2, 3, 4, 5, 6, 7}
	var a1 = [7]int(sl) //4.用slice初始化数组
	fmt.Println(a1)

	var a2 = [7]int{1, 2, 3, 4, 5, 6, 7}
	//var s2 = []int(a2) //4.数组转slice不行
	var s2 = a2[0:]
	fmt.Println(s2)
}

func newArch() {
	//GOOS=freebsd
	//GOARCH=riscv64
}

func IsEqual[T comparable](a T, b T) bool {
	return a == b
}

// remove mention of arena goexperiment
/*
注意,2023-01-17。由于严重的 API 问题,此提案被无限期搁置。GOEXPERIMENT=arena 代码可能随时不兼容地更改或删除,我们不建议在生产中使用它。
https://github.com/golang/go/issues/51317
*/
func arenaMethod() {
	// type T struct {
	// 	val int
	// }

	// a := arena.New()
	// var ptrT *T
	// a.New(&ptrT)
	// ptrT.val = 1

	// var sliceT []T
	// a.NewSlice(&sliceT, 100)
	// sliceT[99].val = 4

	// a.Free()

}


关于arena

官方告诉我们,注意,2023-01-17。由于严重的 API 问题,此提案被无限期搁置。GOEXPERIMENT=arena 代码可能随时不兼容地更改或删除,我们不建议在生产中使用它。所以

我们可以用,但需要包装上一层,免得某天API被踢出去.

package main

import (
	"arena"
)

type myStruct struct {
	val int
}

func main() {
	// 创建一个Arena对象
	are := arena.NewArena()

	// 对比通过new初始化以及通过Arena初始化
	p1 := foo[int]()
	p2 := newStaticPointer[int](are)
	*p2 = 10
	println(*p1)
	println(*p2)

	slice1 := foo2[int](5)
	slice2 := newStaticSlice[int](are, 5)
	slice2[0] = 20
	println(slice1[0])
	println(slice2[0])

	p3 := foo[myStruct]()
	p4 := newStaticPointer[myStruct](are)
	p4.val = 30
	println(p3.val)
	println(p4.val)

	// 调用 Free() 后内存会立即释放,不能继续用arena,但已有的数据还能用
	are.Free()
	p4.val = 300
	println(p4.val) //成功修改
	//newStaticPointer[int](are) //不能继续用arena
}

func foo[T any]() *T {
	return new(T)
}

func foo2[T any](len int, cap ...int) []T {
	c := len
	for _, v := range cap {
		c = v
		break
	}

	return make([]T, len, c)
}

func newStaticPointer[T any](a *arena.Arena) *T {
	t := arena.New[T](a)
	return t
}

func newStaticSlice[T any](a *arena.Arena, len int, cap ...int) []T {
	c := len
	for _, v := range cap {
		c = v
		break
	}

	ts := arena.MakeSlice[T](a, len, c)
	return ts
}