Help explain range form for loops behavior

The code below behaves different based on whether I use the for i := range list followed by x := list[i] and for _, x := range list. My guess was it’s a slightly weirder manifestation of how one can accidentally capture a loop variable in a closure, though I wanted to see if anyone else could explain it away better.

package main

import (
	"fmt"
)

type Log struct {
	Log *string
}

func main() {
	resp := []string{"string1", "string2"}
	
	var logs []*string	
	// uncomment these lines to get the expected behavior
	//for i := range resp {
	//	h := resp[i]
	for _, h := range resp {
		logs = append(logs, &h)
	}
	
	for _, l := range logs {
		fmt.Println(*l)
	}
}
package main

import (
	"fmt"
)

type Log struct {
	Log *string
}

func main() {
	resp := []string{"string1", "string2"}

	var logs []*string
	// each iteration of the loop uses the same
	// instance of the range variable h,
	// so each closure shares that single variable.
	for _, h := range resp {
		h := h // new local variable
		logs = append(logs, &h)
	}
	for _, l := range logs {
		fmt.Println(*l)
	}
}

https://play.golang.org/p/SnETZW17YOh

string1
string2

Go: Frequently Asked Questions (FAQ)
What happens with closures running as goroutines?

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.