It would be helpful if you could link to actual code, preferably on the playground. That error message seems to indicate that you are not using gotip. I got mixed up earlier, when I wrote Go 1.18. I meant Go 1.19, the next Go version.
On Mon, May 23, 2022 at 11:51 AM Zhaoxun Yan <yan.zhao...@gmail.com> wrote: > `&` won't make any difference: > > undefined: atomic.Int32 > > > > On Mon, May 23, 2022 at 4:31 PM Axel Wagner <axel.wagner...@googlemail.com> > wrote: > >> 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/CAEkBMfFa12%2BYAyE_bor9k8PtHRVzWQuq_mzMH2N%3DRcKZRUBe5w%40mail.gmail.com.