go func() {
defer wg.Done()
for i := 0; i < n; i {
ch <- i
}
}()
go func() {
for i := 0; i < n; i {
ch <- i
}
wg.Done()
}()
Are these two code the same? Seems the same running them and I have seen both writings.
CodePudding user response:
Those 2 seem to be identical, there may be cases when they're not. That's because deferred functions are also executed if the function is panicking.
So for example if ch
is a closed channel, sending on a closed channel will panic (see How does a non initialized channel behave?), and without defer
wg.Done()
will not be called. With defer
, it will be. This may be very important for another goroutine calling wg.Wait()
to get unblocked.
Another difference is that the deferred function and its arguments are evaluated when the defer
statement is executed, in your case before the loop. If the wg
variable would be modified e.g. after the first send, the one with defer
would not see the new value of wg
, the one without defer
would see that as it's evaluated after the loop.
All in all, use defer
when it makes sense, and even if you or someone else later end up modifying / extending the code, it will not be forgotten. Just think of an example where someone inserts a conditional return
:
go func() {
defer wg.Done()
for i := 0; i < n; i {
ch <- i
if i == 3 {
return
}
}
}()
Using defer
, this won't be a problem, wg.Wait()
will still be called. Without defer
, it won't be.
See related questions: