Explain race condition with for range of slice and wg.Go

When you have some data in a slice that you need to iterate and then you want to spin up a new goroutine you might face a race condition if you do the following:

var emails []string

// ...

for _, email := range emails {
  go sendEmail(email)
}

A solution would be to force a clone of the variable you need to send to the new goroutine so you avoid several ones reading and updating from the same memory position:

var emails []string

// ...

for _, email := range emails {
  clonedEmail := email
  go sendEmail(clonedEmail)
}