暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Go中值为Nil的slice循环遍历会发生什么

堆栈future 2021-10-20
5400

1. 前言

我们在了解了slice的源码之后得知,它的底层有三个属性,第一个是指向底层数组的指针,第二个是slice的长度,第三个是slice的容量。那当我们定义一个slice的变量的时候,如果给它初始化值是Nil,会发生什么?

2. 实战

先来看看一个例子:

package main

import (
 "fmt"
)

func main() {
 a := []string{"A""B""C""D""E"}
 a = nil
 fmt.Println(a, len(a), cap(a))
}

结果:

[] 0 0

说明a是一个Nil的slice,它的长度和容量都是0。

但是当我们用for range
去遍历值为Nil的slice的时候会出现什么问题呢?

再来看一个例子:

package main

import (
 "fmt"
)

func main() {
 a := []string{"A""B""C""D""E"}
 a = nil
 fmt.Println(a, len(a), cap(a))
 
 for i, j := range a {
  fmt.Println(i, j)
 }
}

结果:

[] 0 0

我们看到结果没有变,也没有报错,for range
到底做了什么才能在遍历值为Nil的slice的时候不报错呢?

答案就在for range
遍历slice的源码中,且看:

编译器对for range的处理流程如下:
  for_temp := range
  len_temp := len(for_temp)
  for index_temp := 0; index_temp < len_temp; index_temp++ {
          value_temp = for_temp[index_temp]
          index = index_temp
          value = value_temp
          origin body

   }

从源码中可以看出,它先得到slice的长度,值为Nil的长度当然是0,所以在for循环遍历的时候,因为长度不满足遍历条件,所以进不去循环,这就证明了值为Nil的切片在for range
遍历的时候是没有问题的。

3. 小结

针对slice的特例我们一定要牢记,因为在项目中会大量使用,而且slice的变量是引用传递,所以在使用之前最好有Nil的断言,否则在传递的过程中无法保证被谁赋值为Nil从而导致程序奔溃。

文章转载自堆栈future,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论