Why Does sync.WaitGroup Work Without a Pointer Receiver?
In Go, the sync.WaitGroup type is used for synchronizing goroutines. The methods of sync.WaitGroup, such as Add, Done, and Wait, are defined with pointer receivers. However, it is common to declare sync.WaitGroup values without a pointer (*).
Consider the following snippet:
package main import ( "fmt" "sync" "time" ) var wg sync.WaitGroup func main() { wg.Add(1) go func() { fmt.Println("starting...") time.Sleep(1 * time.Second) fmt.Println("done....") wg.Done() }() wg.Wait() }
In this code, we declare wg as a sync.WaitGroup value without a pointer (*). This is possible because Go allows for the use of pointer receivers on non-pointer values.
Under the hood, Go converts a non-pointer value (such as in wg.Add(1)) to a pointer value (such as &wg.Add(1)). This allows the methods of sync.WaitGroup to be called on non-pointer values.
Reflection on the Method Set of sync.WaitGroup
The method set of sync.WaitGroup is empty because all its methods have pointer receivers. This is confirmed by the following reflection code:
wg := sync.WaitGroup{} fmt.Println(reflect.TypeOf(wg).NumMethod()) // Outputs 0
This means that sync.WaitGroup does not have any methods that can be called directly on non-pointer values.
Conclusion
It is common in Go to declare sync.WaitGroup values without a pointer (*). This is possible because Go allows for the use of pointer receivers on non-pointer values. The method set of sync.WaitGroup is empty because all its methods have pointer receivers, which are automatically converted from non-pointer values by the compiler.
The above is the detailed content of Why Can Go\'s sync.WaitGroup Work Without a Pointer?. For more information, please follow other related articles on the PHP Chinese website!