Go1.21.0 的惊喜:map 元素清空有了新姿势
2023-6-7 08:53:43 Author: Go语言中文网(查看原文) 阅读量:10 收藏

阅读本文大概需要 2 分钟。

大家好,我是站长 polarisxu。

早在 2022 年 10 月,rsc 就有一个提案:spec: add clear(x) builtin, to clear map, zero content of slice[1],主要原因是干掉类似这样的代码:

for k := range m {
    delete(m, k)
}

目前 Go tip 版本已经有 clear 函数了。它的函数签名如下:

func clear[T ~[]Type | ~map[Type]Type1](t T)

clear 可以清空切片或 map 类型的值,将其底层元素全部置为零值,并保持其切片长度和容量不变。

归纳起来,clear 函数能够解决以下几类问题:

  • 当需要清空一个切片时,以前需要使用 s = s[:0]s = nil 等方式,这些方式不够直观和一致,而且可能会导致内存泄露或性能下降。使用 clear(s) 可以更简洁和高效地完成清空操作,并且保留底层内存。
  • 当需要清空一个 map 时,以前需要使用 for k := range m { delete(m, k) }m = nil 等方式,这些方式不够优雅和安全,而且可能会导致内存浪费或竞争条件。使用 clear(m) 可以更方便和安全地完成清空操作。

总之,当需要将切片或映射类型的值清空时,都可以使用 clear 函数。但是需要注意以下几点:

  • clear 函数只能接受切片或 map 类型的值作为参数,不能接受指向切片或映射类型的值的指针作为参数。如果传入指针,则会导致编译错误,因为类型不匹配。
  • clear 函数可以接受符合切片或 map 的约束泛型作为参数,这样可以实现多态性。约束泛型是一种限制类型参数取值范围的接口,切片或 map 的约束泛型分别是 ~[]Type~map[Type]Type1,其中 TypeType1 是类型参数。
  • clear 函数不支持其他类型的值,例如通道、结构体等。如果想要清空这些类型的值,需要自己定义一个清空函数,或者使用其他方式。
  • clear 函数传入一个字面量不会导致编译错误,但也没有任何效果,因为字面量是不可寻址的值。例如 clear([]int{1, 2, 3})clear(map[string]string{"foo": "bar"})
  • 传入 nil 不会导致错误,相当于啥也没做

以下是一些使用 clear 函数的示例,因为 Go 1.21.0 还未发布,要正常运行下面代码,请安装 Go tip 版本。或者使用 Go playground 运行,地址:https://go.dev/play/p/dgf62WVxPxg?v=gotip。

package main

import (
 "fmt"
)

func main() {
 // clear a slice
 s := []int{1234}
 fmt.Println(s) // [1 2 3 4]
 clear(s)
 fmt.Println(s) // [0 0 0 0]

 // clear a map
 m := map[string]string{"foo""bar""baz""qux"}
 fmt.Println(m) // map[foo:bar baz:qux]
 clear(m)
 fmt.Println(m) // map[]

 // clear a constrained type parameter
 type MySlice []int
 type MyMap map[string]int
 var ms MySlice = []int{5678}
 var mm MyMap = map[string]int{"one"1"two"2}
 fmt.Println(ms) // [5 6 7 8]
 fmt.Println(mm) // map[one:1 two:2]
 clear(ms)
 clear(mm)
 fmt.Println(ms) // [0 0 0 0]
 fmt.Println(mm) // map[]
}

参考资料

[1]

spec: add clear(x) builtin, to clear map, zero content of slice: https://github.com/golang/go/issues/56351


往期推荐

我是 polarisxu,北大硕士毕业,曾在 360 等知名互联网公司工作,10多年技术研发与架构经验!2012 年接触 Go 语言并创建了 Go 语言中文网!著有《Go语言编程之旅》、开源图书《Go语言标准库》等。

坚持输出技术(包括 Go、Rust 等技术)、职场心得和创业感悟!欢迎关注「polarisxu」一起成长!也欢迎加我微信好友交流:gopherstudio


文章来源: http://mp.weixin.qq.com/s?__biz=MzAxMTA4Njc0OQ==&mid=2651454422&idx=1&sn=3017da4b75e8d45b09aa611484c85928&chksm=80bb2524b7ccac32191892530f04492d15eb5c0cd56f4cd6371854838175adcfc2a61d9717bc#rd
如有侵权请联系:admin#unsafe.sh