* Fei Ding <fding...@gmail.com> [160918 02:58]: > Thanks, Marvin, I've learned a lot from your reply. And, I've written more > code, like: > > a, b, c := 1, 2, 3 > > slice1 := []int{a, b, c} > > for _, n := range slice1 { > > go func(n *int) {fmt.Println(*n)}(&n) > > } > > > It seems that pass *n's address *in the code above will make a data race, > which you have already explained why. But still, I have another question: > If the coder do really want the addresses of elements in slice, how to do > it correctly?
* Marvin Stenger <marvin.stenge...@gmail.com> [160918 07:12]: > https://play.golang.org/p/9LQMDrDIOv should work. Marvin Stenger gives two good solutions in the above link. I will explain what each does and why you might use one over the other. for i, _ := range values { go values[i].print() } In this case, the expression values[i].print is evaluated to determine the function to be scheduled, so the function that is scheduled is the print method with an implied first argument of &values[i]. This expression is evaluated prior to scheduling, so neither the variable values nor the variable i are referenced in the goroutine. However, the value of &values[i] is a pointer into the backing array for the slice, which will be important in choosing which solution to use. for _, v := range values { w := v go w.print() } In the second case, although the same v is reused for all iterations of the loop, a new w is created each time through the loop. The assignment to v at the beginning of the loop makes a copy of the slice element and puts it in v. Then it is copied a second time and stored in w. (The compiler may be able to optimize the generated code to avoid making two copies.) Now the function call that is scheduled is a call to the print method with an implied first argument of &w. Because each iteration of the loop uses a new variable w, each goroutine has its own copy of the slice element associated with the iteration of the loop in which the goroutine was created. The primary consideration in choosing between these two solutions is whether or not the goroutine can safely access the slice element in the backing array. If it can, use the first solution. If it cannot, either because the backing array might be modified or because the element itself is not safe to reference concurrently, then use the second solution. I would probably modify the second solution like this: for i, _ := range values { var w = values[i] go w.print() } This doesn't rely on the compiler's ability to optimize copying the element twice into copying it only once, and it is just as clear to the next programmer who reads your code. ...Marvin -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.