exporting a pointer for the loop variable test
34 }
35 for _, test := range tests {
36 t.Run("", func(t *testing.T) {
37 updateRegex = &test.regex38 assert.Equal(t, test.want, Update(test.name))
39 })
40 }
Description
In for
statements (for i, v := range ...
) the iteration variable(s) is reused i.e., at
each iteration, the value of the next element in the range expression is assigned to the
iteration variable; v doesn't change, only its value changes. Hence, the expression &v is
referring to the same location in memory. Hence exporting pointer to loop variable is not
recommended and it often a bug-risk. It is recommended to use the memory by indexing it
(arr[i]
) if it's a slice or array, or by creating a copy (v := v
) instead.
Bad practice
results := make([]*int, 0)
for i, p := range []int{1, 2, 3, 4, 5} {
results = append(results, &p) // bug-risk
fmt.Println(&p)
switch {
case i%3:
intRef = &p // bug-risk
intStr.x = &p // bug-risk
default:
}
}
Recommended
results := make([]*int, 0)
for i, p := range []int{1, 2, 3, 4, 5} {
p := p
results = append(results, &p)
fmt.Println(&p)
switch {
case i%3:
intRef = &p
intStr.x = &p
default:
}
}