我目前正在尝试通过将指针传递给函数来修改切片的元素。在函数之外,元素不会被修改。
有没有办法在不传递切片本身以及要更改的所需元素的索引的情况下修改元素?
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}]
}
Run Code Online (Sandbox Code Playgroud)
for i := range items {
alter(&items[i])
}
Run Code Online (Sandbox Code Playgroud)
或者
items := []*Item{{0}, {1}}
for _, item := range items {
alter(item)
}
Run Code Online (Sandbox Code Playgroud)
您的版本不起作用的原因是迭代变量item保存了切片内元素的副本,这意味着您正在修改的是副本而不是原始元素。如果你运行这个,你可以看到它们是内存中的单独对象:https : //play.golang.org/p/vr9CfX0WQcB
参考:https : //tour.golang.org/moretypes/16
for 循环的范围形式迭代切片或地图。
当对一个切片进行测距时,每次迭代都会返回两个值。第一个是索引,第二个是该索引处元素的副本。
所以,
for i, x := range arr {
// x is copy for arr[i]
}
Run Code Online (Sandbox Code Playgroud)
因此,我们将直接使用arr[i]并将其地址传递给alter函数,以便对其进行修改。
示例代码:
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)
}
Run Code Online (Sandbox Code Playgroud)