修改切片元素使用指针

huangapple go评论75阅读模式
英文:

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}]

}

Golang Playground

英文:

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}]

}

Golang Playground

答案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)
}

【Playground】

英文:

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)
}

[Playground]

huangapple
  • 本文由 发表于 2021年8月6日 10:33:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/68675424.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定