rra*_*rag 4 concurrency pointers go
我见过几个不同的例子sync.WaitGroup
实施例1
var wg sync.WaitGroup
wg.Add(1)
go doStuff(&wg)
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
实施例2
wg := new(sync.WaitGroup)
wg.Add(1)
go doStuff(wg)
wg.Wait()
Run Code Online (Sandbox Code Playgroud)
区别实际上在于sync.WaitGroup
初始化
方式var
与new
如果使用该var
选项,它必须作为&wg
指向 goroutine 的指针传递,但如果我使用该new
选项,我可以将其发送为wg
这两个例子有什么区别?上面这2个哪一个是正确的?在某些情况下,是否优先选择其中一种?
我正在编写一个创建多个 s 的程序,那么使用orsync.WaitGroup
是否重要?new
var
你的两个例子都工作正常。另请注意,除了 之外new()
,您还可以使用复合文字并获取其地址,如下所示:
var wg = &sync.WaitGroup{}
Run Code Online (Sandbox Code Playgroud)
的方法有指针接收器,因此每当调用它的方法时,都需要结构体值sync.WaitGroup
的地址。WaitGroup
这不是问题,因为当wg
是非指针时, andwg.Add(1)
调用是andwg.Done()
的简写,因此编译器会自动“重写”这些调用以获取first 的地址,并使用该地址作为方法的接收者。(&wg).Add(1)
(&wg).Done()
wg
但是,我仍然认为,如果一个值仅用作指针(sync.WaitGroup
这是一个闪亮的示例),那么您应该首先声明它并将其用作指针,这样就可以减少出错的空间。
例如,如果您使用非指针,并且声明该函数需要非指针,并且将其作为非指针传递,则不会出现编译时错误,但它会行为不当(不应sync.WaitGroup
复制)。
尽管今天的 linter 会给您一个警告消息,但我仍然相信最好始终使用指针。
使用指针的另一个原因:如果函数返回 a sync.WaitGroup
,或者如果您有一个存储sync.WaitGroup
为值的映射,则您将无法对结果调用方法,因为函数的返回值和映射索引操作是不可寻址的。如果函数返回一个指针值,或者如果您首先将指针存储在映射中,您仍然可以调用这些方法,而不必将它们存储在局部变量中。有关详细信息,请参阅如何在 Go 中存储对操作结果的引用?
例如:
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
Run Code Online (Sandbox Code Playgroud)
但这些有效:
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
Run Code Online (Sandbox Code Playgroud)
在这里阅读更多相关内容:Go 的构造函数为什么应该返回地址?
归档时间: |
|
查看次数: |
4643 次 |
最近记录: |