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.

Reply via email to