Reputation: 1154
I'm currently trying to modify an element of a slice by passing a pointer to a function. Outside of the function the element is not modified.
Is there a way to modify the element without passing the slice itself along with the index of the desired element to alter?
package main
import (
"fmt"
)
type Item struct {
Value int
}
func alter(t *Item) {
(*t).Value = 100
}
func main() {
items := []Item{Item{0}, Item{1}}
for _, item := range items {
alter(&item)
}
fmt.Println(items) // Output is still [{0} {1}]
}
Upvotes: 3
Views: 2613
Reputation: 4204
Refer: https://tour.golang.org/moretypes/16
The range form of the for loop iterates over a slice or map.
When ranging over a slice, two values are returned for each iteration. The first is the index, and the second is a copy of the element at that index.
So,
for i, x := range arr {
// x is copy for arr[i]
}
Hence, we will directly used arr[i]
and pass the address of the same to the alter
function so that it could be modified.
Sample code:
package main
import "fmt"
type Item struct {
Value int
}
func alter(t *Item) {
(*t).Value = 100
}
func main() {
items := []Item{{0}, {1}}
for i := range items {
alter(&items[i])
}
fmt.Println(items)
}
Upvotes: 4
Reputation: 38213
for i := range items {
alter(&items[i])
}
Or
items := []*Item{{0}, {1}}
for _, item := range items {
alter(item)
}
The reason your version doesn't work is because the iteration variable item
holds a copy of the element inside the slice, which means that what you're modifying is the copy and not the original. You can see that they are separate objects in memory if you run this: https://play.golang.org/p/vr9CfX0WQcB
Upvotes: 7