在Go 1.21中, 增加了和sync.Once有关的三个函数。sync.Once本身实现就非常简单了,新增加的这三个函数到底是干啥的?让我们一起来看看。
sync.Once
我们常常使用sync.Once实现单例模式,它也非常的高效。
下面的代码是官方的一个例子,运行它可以看到onceBody
函数只会被执行一次:
|
|
OnceFunc
|
|
OnceFunc
返回一个可以并发调用的函数,它可以被调用多次。即使返回的函数被调用多次,f
也只会被调用一次。
下面的代码onceBody
只被执行了一次:
|
|
OnceValue
|
|
OnceValue
返回一个函数, 这个函数会返回f的返回值。多次调用都会返回同一个值。
下面的代码中,randvalue
只会被执行一次,返回结果记做n
的话, 并且每次调用bar函数都会返回n
。bar可以并发的被调用。
|
|
同时,可以看到在标准库中,泛型越来越被使用。
OnceValues
|
|
OnceValues
和OnceValue
的功能类似,只不过返回两个参数,仅此而已。
综述一下:
- 这三个函数返回的函数被调用的时候,分别返回0个、1个、2个返回值。
- 返回的函数可以被并发的调用。
- 如果f被执行的时候panic, 返回的函数被调用的时候也会panic,panic的值和f的panic一样。
稍微展开讲一下tuple。
如果想返回更多的返回值,自己模仿构造一个,或者把多个返回值封装到一个对象中。
很多年前,我记得看一篇文章介绍某种编程语言的tuple是硬编码的, 两个元素的tuple、三个元素的tuple、四个元素的tuple等,忘记是哪个语言了。
所以你也可以模仿它。
go-tuple就是这样实现的一个go语言的tuple,最多支持9个元素。
|
|
顺便说一下,上面我介绍的Go 1.21新增的三个内建函数之一的clear
,清除map的时候,只是把map置空,并不会shrink map, 你可以看例子: https://go.dev/play/p/quVwNvAZAGJ?v=gotip 或者相关讨论 https://github.com/golang/go/issues/56351