一尘不染

`sync.WaitGroup`的方法是什么?

go

我下面有这个简单的程序

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()

}

请注意,我使用的var wg sync.WaitGroup是值,而不是指针。但是sync包页面指定AddDoneWait函数采用*sync.WaitGroup

为什么/如何运作?


阅读 249

收藏
2020-07-02

共1个答案

一尘不染

设定方法sync.WaitGroup是空的方法集:

wg := sync.WaitGroup{}
fmt.Println(reflect.TypeOf(wg).NumMethod())

输出(在Go Playground上尝试):

0

这是因为所有方法都sync.WaitGroup具有指针接收器,因此它们都是该*sync.WaitGroup类型的方法集的一部分。

当您这样做时:

var wg sync.WaitGroup

wg.Add(1)
wg.Done()
// etc.

这实际上是的简写(&wg).Add(1)(&wg).Done()等等。

这是在规范中:致电:

如果x是可寻址且&x方法集包含mx.m()则为的简写(&x).m()

因此,当您拥有一个可寻址的值(变量是可寻址的)时,您可以调用在非指针值上具有指针接收器的任何方法,并且编译器将自动获取该地址并将其用作接收器值。

2020-07-02