In Go 1.21, three functions related to sync.Once
have been added. sync.Once
itself is very simple to implement, but what do these three new functions do? Let’s take a look.
sync.Once
We often use sync.Once
to implement the singleton pattern, which is also very efficient.
The code below is an official example, run it and you can see that the onceBody
function will only be executed once.
|
|
OnceFunc
|
|
OnceFunc
returns a function that can be called concurrently, and it can be called more than once. Even if the returned function is called more than once, f
will only be called once.
The following code, onceBody
, is only executed once.
OnceValue
|
|
OnceValue
returns a function which returns the return value of f. Multiple calls will return the same value.
In the code below, randvalue
will only be executed once, returning the result as n
, and each call to the bar function will return n
. bar can be called concurrently.
At the same time, it can be seen that generics are increasingly being used in the standard library.
OnceValues
|
|
OnceValues
and OnceValue
have a similar function, except that they return two parameters, that’s all.
To summarise:
- The three functions returned return 0, 1, and 2 return values respectively when the function is called.
- The returned functions can be called concurrently.
- If f is panic when executed, the returned function will also be panic when called, with the same value as f’s panic.
A little bit of expansion on tuples.
If you want to return more return values, mimic constructing one, or encapsulating multiple return values into a single object.
Many years ago, I remember reading an article about some programming language where tuples were hard-coded, two element tuples, three element tuples, four element tuples, etc. I forget which language it was.
So you can imitate it too.
The go-tuple is such an implementation of a go language tuple, supporting up to 9 elements.
|
|
By the way, the above clear
, when clearing the map, just leaves the map empty, it does not shrink the map, you can see the example at: https://go.dev/play/p/quVwNvAZAGJ?v=gotip or the related discussion at https://github.com/golang/go/issues/56351
Ref
https://colobu.com/2023/05/29/extends-sync-Once/