go的数组(切片)range遍历小坑

原创文章转载请注明出处

go的数组元素可以通过 索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。

可以通过for结构遍历数组,实现以下功能:

  • 通过 for 初始化数组项
  • 通过 for 打印数组元素
  • 通过 for 依次处理元素

for结构的基本使用方式如下:

package main
import "fmt"

func main() {
    var arr1 [5]int

    for i:=0; i < len(arr1); i++ {
        arr1[i] = i * 2
    }

    for i:=0; i < len(arr1); i++ {
        fmt.Printf("Array at index %d is %d\n", i, arr1[i])
    }
}

for 循环中的条件非常重要:i < len(arr1),如果写成 i <= len(arr1) 的话会产生越界错误。所以,我们一般用关键字range来避免这种错误。

for i, v:= range arr1 {
  ...
}

当然以上两种 for 结构对于切片(slices)来说也同样适用。

需要注意的问题来了,通过range遍历得到的value是值拷贝。

type s struct {
    i int
}

func main() {
    m := make([]s, 0)
    m = append(m, s{i: 0})
    m = append(m, s{i: 1})
    m = append(m, s{i: 2})
    for _, e := range m { //e是值拷贝
        e.i = 3
    }
    for _, x := range m {
        fmt.Printf("%v\n", x.i)
    }
}

上述代码第一个for循环中的e是原值的拷贝,所以e.i = 3并没有修改原数组中的元素,所以输出的结果如下:

0
1
2

如果非要在使用range遍历的过程中修改数组内容,那么还是要用下标访问数组元素。

type s struct {
    i int
}

func main() {
    m := make([]s, 0)
    m = append(m, s{i: 0})
    m = append(m, s{i: 1})
    m = append(m, s{i: 2})
    for index := range m { //获取索引
        m[index].i = 3 //通过下标获取元素进行修改
    }
    for _, x := range m {
        fmt.Printf("%v\n", x.i)
    }
}

输出

3
3
3

我是咕咕鸡,一个还在不停学习的全栈工程师。
热爱生活,喜欢跑步,家庭是我不断向前进步的动力。

    原文作者:咕咕鷄
    原文地址: https://www.jianshu.com/p/29699d1babb8
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞