为了账号安全,请及时绑定邮箱和手机立即绑定

多个 sync.WaitGroup 用法

多个 sync.WaitGroup 用法

Go
慕尼黑的夜晚无繁华 2023-05-15 15:38:16
我见过几个不同的例子sync.WaitGroup示例 1var wg sync.WaitGroupwg.Add(1)go doStuff(&wg)wg.Wait()示例 2wg := new(sync.WaitGroup)wg.Add(1)go doStuff(wg)wg.Wait()区别在于sync.WaitGroup初始化 方式var与new如果使用该var选项,它必须作为&wg指向 goroutine 的指针传递,但如果我使用该new选项,我可以将其发送为wg这两个例子有什么区别?以上2个哪一个是正确的?在某些情况下,一个比另一个更受欢迎吗?我正在编写一个创建多个 s 的程序,所以是否使用orsync.WaitGroup有关系吗?newvar
查看完整描述

1 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

您的两个示例都可以正常工作。另请注意,除了new(),您还可以使用复合文字并获取其地址,如下所示:

var wg = &sync.WaitGroup{}

方法有指针接收者,所以无论何时调用它的方法,都需要结构值sync.WaitGroup的地址。WaitGroup这不是问题,因为 whenwg是非指针,wg.Add(1)and调用是andwg.Done()的简写,因此编译器会自动“重写”那些调用以获取first 的地址,并将该地址用作方法的接收者。(&wg).Add(1)(&wg).Done()wg

但是,我仍然认为,如果一个值仅用作指针(sync.WaitGroup这是一个很好的例子),您应该首先声明它并将其作为指针使用,这样可以减少出错的空间。

例如,如果你使用一个非指针并且你声明函数期望一个非指针,并且你将它作为一个非指针传递,你不会得到编译时错误,但它会行为不端(不应该被sync.WaitGroup复制).

尽管今天的 linter 会给你一条警告信息,但我仍然认为最好始终使用指针。

使用指针的另一个原因:如果一个函数将返回一个sync.WaitGroup,或者如果您有一个存储sync.WaitGroup为值的映射,您将无法对结果调用方法,因为函数的返回值和映射索引操作是不可寻址的。如果该函数将返回一个指针值,或者如果您首先将指针存储在映射中,您仍然可以调用这些方法而不必将它们存储在局部变量中。

例如:

func getWg() sync.WaitGroup { return sync.WaitGroup{} }


getWg().Wait() // Compile-time error!


m := map[int]sync.WaitGroup{

    1: sync.WaitGroup{},

}


m[1].Wait() // Again: compile-time error

但是这些工作:


func getWg() *sync.WaitGroup { return &sync.WaitGroup{} }


getWg().Wait() // Works, you can call methods on the return value


m := map[int]*sync.WaitGroup{

    1: &sync.WaitGroup{},

}


m[1].Wait() // Also works


查看完整回答
反对 回复 2023-05-15
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信