On Mon, May 23, 2022 at 10:19 AM Zhaoxun Yan <yan.zhao...@gmail.com> wrote:
> Yes but the syntax is confusing, e.g. the code below fails: > That's because you can't take the address of a call expression. That is, your code is interpreted as &(a.Load()), while you might have intended (&a).Load() <https://go.dev/play/p/tClXJjahCHG?v=gotip>, which you can also just write as a.Load() <https://go.dev/play/p/4HGAscVglX2?v=gotip>. That's not really about the API, it's how the language works. Note that with your original `Global` type, you get exactly the same error if you write &S.Load(). > package main > > import ( > "fmt" > "sync/atomic" > ) > > var a atomic.Int32 > > func main() { > fmt.Println(&a.Load()) > } > > although the manual says: > type Int32 > <https://cs.opensource.google/go/go/+/master:src/sync/atomic/type.go;l=59> > ¶ <https://pkg.go.dev/sync/atomic@master#Int32> > > type Int32 struct { > // contains filtered or unexported fields > } > > An Int32 is an atomic int32. The zero value is zero. > func (*Int32) Load > <https://cs.opensource.google/go/go/+/master:src/sync/atomic/type.go;l=65> > ¶ <https://pkg.go.dev/sync/atomic@master#Int32.Load> > > func (x *Int32 <https://pkg.go.dev/sync/atomic@master#Int32>) Load() int32 > <https://pkg.go.dev/builtin#int32> > > Load atomically loads and returns the value stored in x. > > 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) > > Of course not. Neither can misuse of atomic or sync.Map prevent race. > I have already shown how simple `=` and `==` caused race on reading > occasions in the last post. > Strict prevention should have been enforced at the syntax level just like > GIL in Python or ownership in Rust, > and adding a patch cannot fix loop-holes or side-attacks whatsoever. > > On Mon, May 23, 2022 at 2:56 PM Axel Wagner <axel.wagner...@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.zhao...@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+unsubscr...@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/CAEkBMfFbfPawMDiqpTA9a8FuO%2Be7U2U%2BxpA5LvmvAnsBdzZnJg%40mail.gmail.com.