英文:
Modify slice element using pointer
问题
我正在尝试通过将指针传递给函数来修改切片的元素。在函数外部,元素没有被修改。
有没有一种方法可以修改元素,而不需要将切片本身与要修改的元素的索引一起传递?
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) // 输出仍然是 [{0} {1}]
}
英文:
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}]
}
答案1
得分: 7
for i := range items {
alter(&items[i])
}
或者
items := []*Item{{0}, {1}}
for _, item := range items {
alter(item)
}
你的版本不起作用的原因是迭代变量item
保存的是切片内部元素的副本,这意味着你修改的是副本而不是原始元素。如果你运行这段代码,你会发现它们在内存中是独立的对象:https://play.golang.org/p/vr9CfX0WQcB
英文:
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
答案2
得分: 4
参考:https://tour.golang.org/moretypes/16
for循环的range形式用于迭代切片或映射。
当对切片进行迭代时,每次迭代会返回两个值。第一个值是索引,第二个值是该索引处元素的副本。
因此,
for i, x := range arr {
// x是arr[i]的副本
}
因此,我们将直接使用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)
}
英文:
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)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论