目 录CONTENT

文章目录

Golang1.22新特性

Sakura
2024-02-18 / 0 评论 / 0 点赞 / 13 阅读 / 5074 字 / 正在检测是否收录...

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)
    }
}

0

评论区