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

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

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从而导致程序奔溃。

相关文章
|
4天前
|
Go 索引
Go 语言中同一 slice 上的切片其底层数组是否是同一个
Go 语言中同一 slice 上的切片其底层数组是否是同一个
24 0
|
4天前
|
Go 索引
掌握Go语言:Go语言范围,优雅遍历数据结构,简化代码操作实战解析(24)
掌握Go语言:Go语言范围,优雅遍历数据结构,简化代码操作实战解析(24)
|
4天前
|
Go
Go 1.22 for 循环的两处重要更新
本文介绍了 Go 1.22 版本对 for 循环所做的两处重要更新:循环的每次迭代都会创建新变量 和 循环支持对整数范围进行迭代。 - 循环的每次迭代都会创建新变量,有效避免了以往版本中常见的闭包陷阱,提高了代码的安全性和可预测性。 - 循环支持对整数范围进行迭代,极大地增强了 for 循环的灵活性,使得编写计数循环更加直接和简洁。
58 1
Go 1.22 for 循环的两处重要更新
|
4天前
|
JSON JavaScript Go
Go 语言学习指南:变量、循环、函数、数据类型、Web 框架等全面解析
掌握 Go 语言的常见概念,如变量、循环、条件语句、函数、数据类型等等。深入了解 Go 基础知识的好起点是查阅 Go 官方文档
555 2
|
4天前
|
存储 安全 Java
Go 基础数据结构的底层原理(slice,channel,map)
Go 基础数据结构的底层原理(slice,channel,map)
56 0
|
4天前
|
Go 数据处理
Go杂记1-切片Slice作为函数参数那点事儿
Go杂记1-切片Slice作为函数参数那点事儿
7 0
|
4天前
|
Go 开发者
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
【4月更文挑战第21天】本文介绍了Go语言中的流程控制语句,包括`if`、`switch`和`for`循环。`if`语句支持简洁的语法和初始化语句,但需注意比较运算符的使用。`switch`语句提供多分支匹配,可省略`break`,同时支持不带表达式的形式。`for`循环有多种形式,如基本循环和`for-range`遍历,遍历时修改原集合可能导致未定义行为。理解并避免易错点能提高代码质量和稳定性。通过实践代码示例,可以更好地掌握Go语言的流程控制。
22 3
Golang深入浅出之-Go语言流程控制:if、switch、for循环详解
|
4天前
|
存储 编译器 Go
Golang深入浅出之-掌握Go语言Map:初始化、增删查改与遍历
【4月更文挑战第21天】Go语言中的`map`提供快速的键值对操作,包括初始化、增删查改和遍历。初始化时,推荐使用`make()`函数,如`make(map[string]int)`。插入和查询键值对直接通过索引访问,更新则重新赋值。删除键值对需用`delete()`函数,确保键存在。遍历map常用`for range`,注意避免在遍历中修改map。了解这些并避免易错点,能提升代码效率和可读性。
22 1
Golang深入浅出之-掌握Go语言Map:初始化、增删查改与遍历
|
4天前
|
程序员 Go API
【Go语言快速上手(二)】 分支与循环&函数讲解
【Go语言快速上手(二)】 分支与循环&函数讲解
|
4天前
|
Go C语言 索引
掌握Go语言:探索Go语言中的循环奇妙世界,从基础到实战(13)
掌握Go语言:探索Go语言中的循环奇妙世界,从基础到实战(13)