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.
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 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 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.
OnceValue have a similar function, except that they return two parameters, that’s all.
- 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