首页 >后端开发 >Golang >为什么在循环内更新 Go 结构体中的值不会修改原始结构体?

为什么在循环内更新 Go 结构体中的值不会修改原始结构体?

DDD
DDD原创
2024-11-16 15:07:03323浏览

Why Does Updating Values in a Go Struct Inside a Loop Not Modify the Original Struct?

更新结构中的值

处理结构时,更新值可能会带来挑战。考虑以下代码:

ftr := FTR{}

err = yaml.Unmarshal([]byte(yamlFile), &ftr)

for index, element := range ftr.Mod {

    switch element.Type {
    case “aaa”, “bbbb”:
        element.Type = "cccc”
    case "htr”:
        element.Type = "com"
    case "no":
        element.Type = "jnodejs"
    case "jdb”:
        element.Type = "tomcat"
    }

}

执行此循环后,原始 ftr 结构体并未被修改,尽管循环内有明显的更新。可能是什么问题?

问题:指针和结构体解包

在 Go 中,按值将结构体传递给函数会创建该结构体的副本,这与通过引用传递,它提供了指向原始结构的指针。在这种情况下,使用 range 迭代 ftr.Mod 会创建 Mod 元素的副本,这意味着循环内所做的任何更改都不会反映在原始 ftr 结构中。

解决方案:使用索引和指针

要修改原始 ftr 结构体,请按照以下步骤操作:

  1. 使用索引进行迭代:迭代 ftr.Mod 的索引,而不是元素本身。
  2. 使用指针:将结构体定义中的 Mod 类型更改为 []*Mod。
  3. 访问指针:在循环中,使用指针访问 Mod 元素的值: *ftr.Mod[index].

修改后的代码如下:

type FTR struct {
    Id       string     
    Mod      []*Mod  // Use pointers for Mod
}

for index := range ftr.Mod{
    switch (*ftr.Mod[index]).Type {
    case “aaa”, “bbbb”:
        (*ftr.Mod[index]).Type = "cccc”
    case "htr”:
        (*ftr.Mod[index]).Type = "com"
    case "no":
        (*ftr.Mod[index]).Type = "jnodejs"
    case "jdb”:
        (*ftr.Mod[index]).Type = "tomcat"
    }

}

通过使用指针,可以直接修改原始ftr结构中的值。

以上是为什么在循环内更新 Go 结构体中的值不会修改原始结构体?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn