【问题标题】:Append content to slice into a nested struct does not work将内容附加到嵌套结构中不起作用
【发布时间】:2021-10-06 17:56:27
【问题描述】:

我有两个这样的嵌套结构:

type Block struct {
    ID       string
    Contents []string
}

type Package struct {
    Name   string
    Blocks []Block
}

当我尝试在特定块中附加新内容时,原始包 (p) 不会更改。

for _, b := range p.Blocks {
    if b.ID == "B1" {
        fmt.Println("Adding a new content")
        b.Contents = append(b.Contents, "c3")
    }
}

例子:

https://play.golang.org/p/5hm6RjPFk8o

【问题讨论】:

    标签: go struct append slice


    【解决方案1】:

    当您在切片上循环时,从切片中检索到的每个单独的值都是切片中相应元素的副本。因此,要修改切片中的元素,而不是副本,您可以使用索引表达式直接访问该元素。或者你可以使用指针。请注意,指针也会被复制,但复制的指针将指向与切片中的元素相同的地址,因此可用于直接修改相同的数据。


    您可以使用索引:

    for i := range p.Blocks {
        if p.Blocks[i].ID == "B1" {
            fmt.Println("Adding a new content")
            p.Blocks[i].Contents = append(p.Blocks[i].Contents, "c3")
        }
    }
    

    https://play.golang.org/p/di175k18YQ9


    或者你可以使用指针:

    type Block struct {
        ID       string
        Contents []string
    }
    
    type Package struct {
        Name   string
        Blocks []*Block
    }
    
    for _, b := range p.Blocks {
        if b.ID == "B1" {
            fmt.Println("Adding a new content")
            b.Contents = append(b.Contents, "c3")
        }
    }
    

    https://play.golang.org/p/1RjWlCZkhYv

    【讨论】:

      【解决方案2】:

      发生这种情况是因为这一行:

      for _, b := range p.Blocks {
      

      为切片中的每个Block 创建一个副本。因此,当您随后在循环体中进行更改时,您会将它们更改为 Block 的副本,而不是切片中的 Block

      如果您改为使用索引来获取指向每个 Block 的指针,例如

      for i := range p.Blocks {
          b := &p.Blocks[i]
      

      它按预期工作:

      https://play.golang.org/p/h_nXEX9oWRT

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-07
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 2021-07-17
        • 2012-12-01
        • 2019-04-13
        • 2016-01-11
        相关资源
        最近更新 更多