Golang workGroup

package main

import (
	"fmt"
	"sync"
	"time"
)

func main() {
	start := time.Now()
	var wg sync.WaitGroup
	wg.Add(2)
	ch := make(chan string)
	go sell(ch, &wg)
	go buy(ch, &wg)
	wg.Wait()
	close(ch)
	elapsed := time.Since(start)
	fmt.Println(start, elapsed)
}

// send data to the channel
func sell(ch chan string, wg *sync.WaitGroup) {
	ch <- "furniture"
	fmt.Println("sending data to the channel")
	wg.Done()
}

// receive data from the channel
func buy(ch chan string, wg *sync.WaitGroup) {
	fmt.Println("waiting for data")
	val := <-ch
	fmt.Println("received data: ", val)
	wg.Done()
}

when i pass the address of wg in sell and buy , so , wg.Done() will mark task as done ,in original main function’s wg variable right ?

Correct, because you are passing a pointer to the wg variable declared in main.

You must always use pointers to pass WaitGroup or any other synchronization object from the sync package as a function parameter. They do not support having copies made of them (which is what happens when a function argument is not pointer).