> It's best to be intentional about it and explicitly acquire and release a mutex around the critical sections of your code - because ultimately, only your code knows which sections are critical.
That's really essential. For example, using your library, the following code is most definitely *not* race-free: tmp := v.Load() tmp = tmp + 1 v.Save(tmp) The mutex has to protect the entire sequence, not the individual load and save operations. On Monday, 23 May 2022 at 07:57:02 UTC+1 axel.wa...@googlemail.com wrote: > Just to be clear, are you aware of the sync/atomic package? > https://pkg.go.dev/sync/atomic > There are also some changes in there for Go 1.18, specifically the > addition of some types, so that only atomic operations can be done: > https://pkg.go.dev/sync/atomic@master > I mention this because atomic.Value and atomic.Pointer[T] are essentially > what you are suggesting here. > > On Mon, May 23, 2022 at 8:04 AM Zhaoxun Yan <yan.z...@gmail.com> wrote: > >> However, as I want to narrow the scope of this type down to generate >> integer types (as in the commented code), it encountered two obstacles: >> >> 1) It is not legal to embed a generic inside a struct, nor can it make >> generalized computation =+1 >> >> 2) Inheritance is not available in golang, so type "Counter" cannot >> inherit type "Global" and get its methods automatically. I need to repeat >> Save and Load methods to "Counter". >> >> Am I correct? Or can you improve it? >> > > You are correct that there is no way in Go to write a type which gets all > methods from an embedded field using generics. However, that is a good > thing. For example, say you could write > > type Locked[T any] struct { > sync.Mutex > T > } > > And this would get the methods of T and the methods of sync.Mutex. Then a > user could do > > type Counter int64 > func (c *Counter) Increment() { *c += 1 } > > func main() { > var c Locked[Counter] > go c.Increment() > go c.Increment() > } > > And get a data race. That is, a method can modify a value in a way that is > incompatible with what your wrapper type is trying to do. > > That's really the crux of both of the obstacles you mention. You can't run > arbitrary computations and you can't promote methods, because *not all > computation and not all methods can be made concurrency safe this way*. > > It's best to be intentional about it and explicitly acquire and release a > mutex around the critical sections of your code - because ultimately, only > your code knows which sections are critical. > > >> > -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/baa74bff-6688-4d39-843b-c99a4fea2d1an%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/baa74bff-6688-4d39-843b-c99a4fea2d1an%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/50d6ab3d-46d0-4357-b5fa-d99b73ef2adan%40googlegroups.com.