Golang 1.22 新特性
1. for range
1.1 for range 临时变量的问题
Golang1.22之前
for range 的 k , v 在这个循环过程中都是复用同一块内存空间的
func main() {
// golang1.21
wg := sync.WaitGroup{}
values := []string{"Sakura", "LF", "SSS"}
wg.Add(len(values))
for _, v := range values {
go func() {
defer wg.Done()
println(v)
}()
}
wg.Wait()
}
因为 for 循环很快,而开启协程需要时间,所以等到协程开启了执行后,for 已经基本遍历完了。
所以第一个协程取到 v 已经是最后一个元素了
Golang 1.22 之后
for range 每次循环会为 k , v 单独申请一篇内存空间
三次循环中,三个 k,v 的地址是不一样的
func main() {
// golang1.21
wg := sync.WaitGroup{}
values := []string{"Sakura", "LF", "SSS"}
wg.Add(len(values))
for _, v := range values {
fmt.Printf("%p\n", &v) // 三个地址是同一
go func() {
defer wg.Done()
fmt.Println(v)
}()
}
wg.Wait()
}
因为 v 改变了,所以每个协程获得的上下文也是不一样的
1.2 新的遍历方式
func main() {
// 包含0,但是不包含5
for i := range 5 {
fmt.Println(i)
}
}
2. 随机数相关
import (
"math"
"math/rand"
rand2 "math/rand/v2"
"testing"
)
func BenchmarkRand(b *testing.B) {
for i := 0; i < b.N; i++ {
rand.Intn(math.MaxInt64)
}
}
func BenchmarkRandV2(b *testing.B) {
for i := 0; i < b.N; i++ {
rand2.IntN(math.MaxInt64)
}
}
// >go test -bench=Benchmark -v -benchmem
可以看到新版本的随机数生成性能快了将近一倍
3. 拼接切片
func main() {
s1 := []int{1, 2, 3}
s2 := []int{4, 5, 6}
s3 := []int{7, 8, 9}
// 1.22之前拼接三个切片
newSlices := append(s1, s2...)
newSlices = append(newSlices, s3...)
fmt.Println(newSlices)
// 1.22之后拼接三个切片
newSlice := slices.Concat(s1, s2, s3)
fmt.Println(newSlice)
}
4. http 路由
1.22之前
func main() {
mux := http.NewServeMux()
// restful 风格参数
mux.HandleFunc("/api/v1/{name}", func(writer http.ResponseWriter, request *http.Request) {
// 1.22之前需要自己限制请求方法
if request.Method != "GET" {
writer.Write([]byte("本接口只支持GET请求"))
} else {
fmt.Fprintf(writer, "你好 ,"+request.PathValue("name"))
}
})
if err := http.ListenAndServe("127.0.0.1:8080", mux); err != nil {
panic(err)
}
}
1.22 之后
func main() {
mux := http.NewServeMux()
// restful 风格参数
mux.HandleFunc("GET /api/v1/{name}", func(writer http.ResponseWriter, request *http.Request) {
fmt.Fprintf(writer, "你好 ,"+request.PathValue("name"))
})
if err := http.ListenAndServe("127.0.0.1:8080", mux); err != nil {
panic(err)
}
}
评论区