【问题标题】:Modify slice element using pointer使用指针修改切片元素
【发布时间】:2021-10-10 23:37:50
【问题描述】:

我目前正在尝试通过将指针传递给函数来修改切片的元素。在函数之外,元素不会被修改。

有没有一种方法可以在不传递切片本身以及要更改的所需元素的索引的情况下修改元素?

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

【问题讨论】:

标签: go pointers


【解决方案1】:
for i := range items {
    alter(&items[i])
}

或者

items := []*Item{{0}, {1}}

for _, item := range items {
    alter(item)
}

您的版本不起作用的原因是迭代变量item 保存了切片内元素的副本,这意味着您正在修改的是副本而不是原版的。如果您运行以下命令,您可以看到它们是内存中的单独对象:https://play.golang.org/p/vr9CfX0WQcB

【讨论】:

    【解决方案2】:

    参考:https://tour.golang.org/moretypes/16

    for 循环的范围形式迭代切片或映射。

    在切片上进行测距时,每次迭代都会返回两个值。第一个是索引,第二个是该索引处元素的副本。

    所以,

    for i, x := range arr {
        // x is copy for 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]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-10-16
      • 2015-05-01
      • 2017-07-31
      • 2012-08-21
      • 2020-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多