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

为什么在 Go 范围循环中修改结构体不会更新原始切片?

DDD
发布: 2024-12-20 10:45:09
原创
446 人浏览过

Why doesn't modifying a struct in a Go range loop update the original slice?

Go 中的结构遍历

在 Go 中,当遍历结构体切片时,从 range 变量获得的值是副本。因此,对这些值进行的任何修改都不会影响原始切片。

考虑以下示例:

package main

import (
    "fmt"
)

type myStruct struct {
    Name  string
    Count int
}

func main() {
    chartRecords := []myStruct{}

    for i := 0; i < 5; i++ {
        n := myStruct{Count: i, Name: fmt.Sprintf("Joe%2d", i)}
        chartRecords = append(chartRecords, n)
    }

    fmt.Printf("======ORIGINAL VALUES========\n")
    for _, elem := range chartRecords {
        fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name)
    }

    fmt.Printf("======MODIFIED VALUES EXPECTED========\n")
    for _, elem := range chartRecords {
        elem.Count++
        fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name)
    }

    fmt.Printf("======CHECK AGAIN AND VALUES ARE BACK TO ORIGINAL========\n")
    for _, elem := range chartRecords {
        fmt.Printf("No: %2d | Count: %2d | Name = %s\n", elem.Count, elem.Name)
    }
}
登录后复制

运行此代码将产生以下输出:

======ORIGINAL VALUES========
No:  0 | Count:  0 | Name = Joe 0
No:  1 | Count:  1 | Name = Joe 1
No:  2 | Count:  2 | Name = Joe 2
No:  3 | Count:  3 | Name = Joe 3
No:  4 | Count:  4 | Name = Joe 4
======MODIFIED VALUES EXPECTED========
No:  1 | Count:  1 | Name = Joe 0
No:  2 | Count:  2 | Name = Joe 1
No:  3 | Count:  3 | Name = Joe 2
No:  4 | Count:  4 | Name = Joe 3
No:  5 | Count:  5 | Name = Joe 4
======CHECK AGAIN AND VALUES ARE BACK TO ORIGINAL========
No:  0 | Count:  0 | Name = Joe 0
No:  1 | Count:  1 | Name = Joe 1
No:  2 | Count:  2 | Name = Joe 2
No:  3 | Count:  3 | Name = Joe 3
No:  4 | Count:  4 | Name = Joe 4
登录后复制

如您所见,即使我们增加了范围内每个元素的 Count 字段,chartRecords 切片中的值也不会被修改。这是因为范围变量 elem 是切片中原始元素的副本。

要更新原始切片,需要将更新后的元素分配回相应索引处的切片:

for i, elem := range chartRecords {
    elem.Count++
    chartRecords[i] = elem
}
登录后复制

进行此更正后,再次运行代码将产生以下输出:

======ORIGINAL VALUES========
No:  0 | Count:  0 | Name = Joe 0
No:  1 | Count:  1 | Name = Joe 1
No:  2 | Count:  2 | Name = Joe 2
No:  3 | Count:  3 | Name = Joe 3
No:  4 | Count:  4 | Name = Joe 4
======MODIFIED VALUES EXPECTED========
No:  1 | Count:  1 | Name = Joe 0
No:  2 | Count:  2 | Name = Joe 1
No:  3 | Count:  3 | Name = Joe 2
No:  4 | Count:  4 | Name = Joe 3
No:  5 | Count:  5 | Name = Joe 4
======CHECK AGAIN AND VALUES ARE STILL MODIFIED========
No:  1 | Count:  1 | Name = Joe 0
No:  2 | Count:  2 | Name = Joe 1
No:  3 | Count:  3 | Name = Joe 2
No:  4 | Count:  4 | Name = Joe 3
No:  5 | Count:  5 | Name = Joe 4
登录后复制

现在,chartRecords 切片中的值已更新正如预期的那样。

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

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板