Go中的nil切片和空切片区别详解

Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil。

func main() {
  var s1 []int  // nil切片
  s2 := make([]int,0) // 空切片
  s4 := make([]int,0)  // 空切片
  s5 := []int{} // 空切片
}

直接看代码,不同声明方式:使用 make() 函数生成的切片一定发生了内存分配操作,但给定开始与结束位置(包括切片复位)的切片只是将新的切片结构指向已经分配好的内存区域,设定开始与结束位置,不会发生内存分配操作。这里的内存分配我理解的就是引用数组指针地址

  • nil切片和空切片指向的地址不一样。nil空切片引用数组指针地址为0(无指向任何实际地址)
  • 空切片的引用数组指针地址是有的,且固定为一个值

我们看看切片的数据结构:

type SliceHeader struct {
 Data uintptr //引用数组指针地址
 Len int   // 切片的目前使用长度
 Cap int   // 切片的容量
}

nil切片和空切片最大的区别在于指向的数组引用地址是不一样的。

所有的空切片指向的数组引用地址都是一样的

示例

 package main

import "fmt"

func main(){
 var a []int
 b:=make([]int,0)
 if a==nil{
 fmt.Println("a is nil")
 }else{
 fmt.Println("a is not nil")
 }
 if b==nil{
 fmt.Println("b is nil")
 }else{
 fmt.Println("b is not nil")
 }
}

运行结果:
a is nil
b is not nil

Process finished with exit code 0

因此:
通过var a []int创建的切片是一个nil切片
通过b:=make([]int,0)创建的是一个空切片,(底层数组为空,但底层数组指针非空)

到此这篇关于Go中的nil切片和空切片区别详解的文章就介绍到这了,更多相关Go nil切片和空切片内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅谈golang slice 切片原理

    slice介绍 数组的长度在定义之后无法再次修改:数组是值类型,每次传递都将产生一份副本.显然这种数据结构无法完全满足开发者的真实需求.在初始定义数组时,我们并不知道需要多大的数组,因此我们就需要"动态数组".在Go里面这种数据结构叫slice,slice并不是真正意义上的动态数组,而是一个引用类型.slice总是指向一个底层array,slice的声明也可以像array一样,只是不需要长度,它是可变长的,可以随时往slice里面加数据. 初看起来,数组切片就像一个指向数组的指针,实际

  • go切片的copy和view的使用方法

    语义理解切片 go 语言中的切片是 go 语言的一个特色,从语义上来说,切片就是把一个整体的东西切分成小的部分,那么对于语言中的切片也是同理. 举个例子看如下代码: package main import "fmt" func main() { arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7} fmt.Println("arr[2:6]:", arr[2:6]) // 从下标2到下标6 fmt.Println("arr[:6]

  • GO语言数组和切片实例详解

    本文实例讲述了GO语言数组和切片的用法.分享给大家供大家参考.具体分析如下: 一.数组 与其他大多数语言类似,Go语言的数组也是一个元素类型相同的定长的序列. (1)数组的创建. 数组有3种创建方式:[length]Type .[N]Type{value1, value2, ... , valueN}.[...]Type{value1, value2, ... , valueN} 如下: 复制代码 代码如下: func test5() {     var iarray1 [5]int32    

  • 如何在Go中使用切片容量和长度

    来做一个快速测验-以下代码输出什么? vals := make([]int, 5) for i := 0; i < 5; i++ { vals = append(vals, i) } fmt.Println(vals) Run it on the Go Playground → https://play.golang.org/p/7PgUqBdZ6Z 如果猜到了[0 0 0 0 0 0 1 2 3 4],那么你是正确的. 等一下为什么不是[0 1 2 3 4]? 如果答错了,也不担心.从其他语言

  • Go语言中切片使用的注意事项小结

    前言 Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素: 指向底层数组的指针 slice目前使用到的底层数组的元素个数,即长度 底层数组的最大长度,即容量 因此当我们定义一个切片变量,s := make([]int, 5, 10),即为指向了一个最大长度为10的底层数组,目前切片s使用到的长度为5. 在使用切片的时候,有几个注意事项,下面来一起看看吧. 使用append 先看一个例子: // 创建一个整型切片 // 其长度和容量都是 5 个元素 slice :=

  • Golang中切片的用法与本质详解

    前言 Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大 Go的切片类型为处理同类型数据序列提供一个方便而高效的方式. 切片有些类似于其他语言中的数组,但是有一些不同寻常的特性. 本文将深入切片的本质,并讲解它的用法. 数组 Go的切片是在数组之上的抽象数据类型,因此在了解切片之前必须要先理解数组. 数组类型定义了长度和元素类型.例如, [4

  • Go语言实现字符串切片赋值的方法小结

    前言 在所有编程语言中都涉及到大量的字符串操作,可见熟悉对字符串的操作是何等重要.本文通过示例详细介绍了Go语言实现字符串切片赋值的方法,感兴趣的朋友们跟着小编一起来看看吧. 1. 在for循环的range中 func StrRangeTest() { str := []string{"str1", "str2", "str3"} for i, v := range str { fmt.Println(i, v) v = "test&q

  • golang常用手册之切片(Slice)原理

    切片,这是一个在go语言中引入的新的理念.它有一些特征如下: 对数组抽象 数组长度不固定 可追加元素 切片容量可增大 容量大小成片增加 我们先把上面的理念整理在这里,但是实际的还是要撸码来解决问题. 定义或申明切片 首先我们看看申明切片: var sliceName []type 定义完成后,我们需要定义切片: sliceName = make([]type, len) 也可以适当简写: sliceName := make([]type, len) 在上面的例子中,我们申明了一个切片,我们现在先

  • 深入解析Go语言编程中slice切片结构

    数组转换成切片 复制代码 代码如下: a := [10]int{} fmt.Println(a)  s1 := a[:10]  //取前10个元素 [5:]取 5-最后的元素  fmt.Println(s1) slice测试 复制代码 代码如下: a := []byte{'a', 'b', 'c', 'd', 'e', 'f', 'h'} sa := a[2:5] fmt.Println(string(sa)) sd1 := a[3:5] fmt.Println(string(sd1)) //看

  • 深入理解Go语言中的数组和切片

    一.类型 数组是值类型,将一个数组赋值给另一个数组时,传递的是一份拷贝. 切片是引用类型,切片包装的数组称为该切片的底层数组. 我们来看一段代码 //a是一个数组,注意数组是一个固定长度的,初始化时候必须要指定长度,不指定长度的话就是切片了 a := [3]int{1, 2, 3} //b是数组,是a的一份拷贝 b := a //c是切片,是引用类型,底层数组是a c := a[:] for i := 0; i < len(a); i++ { a[i] = a[i] + 1 } //改变a的值后

随机推荐