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
- 1 回答
- 0 关注
- 107 浏览
添加回答
举报