The method set of a type determines the interfaces that the type implements and the methods that can be called using a receiver of that type

In sync package we have waitgroup

Waitgroup has function Wait() , done() , Add().
All of these functions have RECEIVER type of pointer (wg *waitgroup)

but the below code works

package main

import (
	"fmt"
	"runtime"
	"sync"
)

var wg sync.WaitGroup

func main() {
	fmt.Println("OS\t\t", runtime.GOOS)
	fmt.Println("ARCH\t\t", runtime.GOARCH)
	fmt.Println("CPUs\t\t", runtime.NumCPU())
	fmt.Println("Goroutines\t", runtime.NumGoroutine())

	wg.Add(1) // How is this possible (wg variable is not of pointer type)
	go foo()
	bar()

	fmt.Println("CPUs\t\t", runtime.NumCPU())
	fmt.Println("Goroutines\t", runtime.NumGoroutine())
	wg.Wait()
}

func foo() {
	for i := 0; i < 10; i++ {
		fmt.Println("foo:", i)
	}
	wg.Done()
}

I am new to GO . Please help me understand this concept

1 Like

I guess I got it…

The reason why it is working is since wait() , done(), add() all are the “method sets” of type WaitGroup…hence these methods present in the “method set” can be called by a receiver of that type

1 Like

That works because the compiler knows that Add requires a pointer to a WaitGroup and implicitly “converts” the function call from wg.Add(1) to (&wg).Add(1)

Similarly, when you have a pointer to a value and call a function whose receiver is a value type, there’s a stub function the compiler generates to copy the pointed-to value into a temporary to call the value function on the value.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.