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.
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
chis a closed channel, sending on a closed channel will panic (see How does a non initialized channel behave?), and withoutdeferwg.Done()will not be called. Withdefer, it will be. This may be very important for another goroutine callingwg.Wait()to get unblocked.Another difference is that the deferred function and its arguments are evaluated when the
deferstatement is executed, in your case before the loop. If thewgvariable would be modified e.g. after the first send, the one withdeferwould not see the new value ofwg, the one withoutdeferwould see that as it's evaluated after the loop.All in all, use
deferwhen 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 conditionalreturn:Using
defer, this won't be a problem,wg.Wait()will still be called. Withoutdefer, it won't be.See related questions:
Proper way to release resources with defer in a loop?
The deferred call's arguments are evaluated immediately