返回顶部
首页 > 资讯 > 精选 >Go 语言中 nil 切片、非 nil 切片、空切片
  • 805
分享到

Go 语言中 nil 切片、非 nil 切片、空切片

go语言 2024-02-08 21:02:36 805人浏览 安东尼
摘要

PHP小编小新为你带来了关于Go语言中的切片类型的介绍。在Go语言中,切片有三种状态:nil切片、非nil切片和空切片。这三种切片状态在使用时具有不同的含义和特点。了解这些切片类型的区

PHP小编小新为你带来了关于Go语言中的切片类型的介绍。在Go语言中,切片有三种状态:nil切片、非nil切片和空切片。这三种切片状态在使用时具有不同的含义和特点。了解这些切片类型的区别,将有助于我们更好地理解和使用Go语言中的切片功能。接下来,让我们一起来探索这三种切片类型的具体特点和用法。

问题内容

我是 Go 编程的新手。我在Go编程书中读到,切片由三部分组成:指向数组的指针、长度和容量。

我对以下内容感到困惑:

  • nil 切片(切片没有指向的底层数组,len = 0,cap=0)
  • 仅 len = 0、cap = 0 的非零切片
  • 空切片。

谁能告诉我 nil 和空切片是否是同一件事? 如果两者不同,那么请告诉我这两者有什么区别?如何测试切片是否为空?另外,指针在长度和容量为零的非零切片中保存什么值?

解决方法

可观察的行为

nil 和空切片(容量为 0)并不相同,但它们的可观察行为是相同的(几乎始终)。我的意思是:

  • 您可以将它们传递给内置 len()cap() 函数
  • 您可以 for range 覆盖它们(将是 0 次迭代)
  • 您可以对它们进行切片(只要不违反规范:切片表达式中概述的限制;因此结果也将是一个空切片)
  • 由于它们的长度为 0,因此您无法更改其内容(附加值会创建新的切片值)

查看这个简单的示例(一个 nil 切片和 2 个非 nil 空切片):

var s1 []int         // nil slice
s2 := []int{}        // non-nil, empty slice
s3 := make([]int, 0) // non-nil, empty slice

fmt.Println("s1", len(s1), cap(s1), s1 == nil, s1[:], s1[:] == nil)
fmt.Println("s2", len(s2), cap(s2), s2 == nil, s2[:], s2[:] == nil)
fmt.Println("s3", len(s3), cap(s3), s3 == nil, s3[:], s3[:] == nil)

for range s1 {}
for range s2 {}
for range s3 {}

输出(在 Go Playground 上尝试一下):

s1 0 0 true [] true
s2 0 0 false [] false
s3 0 0 false [] false

(请注意,对 nil 切片进行切片会生成 nil 切片,对非 nil 切片进行切片会生成非 nil 切片。)

除了例外之外,您只能通过将切片值与预声明的标识符 nil 进行比较来区分,它们在其他方面的行为都是相同的。 但请注意,许多软件包确实会将切片与 nil 进行比较,并且可能会基于此进行不同的操作(例如 encoding/ JSONfmt 包)。

唯一的区别是将切片转换为数组指针(已添加到Go 1.17 中的语言)。将非 nil 切片转换为数组指针将生成非 nil 指针,将 nil 切片转换为数组指针将生成 nil 指针。

要判断切片是否为空,只需将其长度与 0 进行比较:len(s) == 0。无论它是 nil 切片还是非 nil 切片,它是否具有正容量也并不重要;如果没有元素,则为空。

s := make([]int, 0, 100)
fmt.Println("Empty:", len(s) == 0, ", but capacity:", cap(s))

打印(在 Go Playground 上尝试一下):

Empty: true , but capacity: 100

底层

切片值由 reflect.SliceHeader 中定义的结构表示:

type SliceHeader struct {
    Data uintptr
    Len  int
    Cap  int
}

对于 nil 切片,该结构将具有其零值,即其所有字段都将为零值,即:0

如果非 nil 切片的容量和长度等于 0LenCap 字段,则很可能是 0,但 Data 指针可能不是。它不会,这就是它与 nil 切片的区别。它将指向一个零大小的底层数组。

请注意,Go 规范允许大小为 0 的不同类型的值具有相同的内存地址。 规范:系统注意事项:大小和对齐保证:

让我们检查一下。为此,我们调用 unsafe 包的帮助,并“获取” reflect.SliceHeader 结构“视图” “我们的切片值:

var s1 []int
s2 := []int{}
s3 := make([]int, 0)

fmt.Printf("s1 (addr: %p): %+8v\n",
    &s1, *(*reflect.SliceHeader)(unsafe.Pointer(&s1)))
fmt.Printf("s2 (addr: %p): %+8v\n",
    &s2, *(*reflect.SliceHeader)(unsafe.Pointer(&s2)))
fmt.Printf("s3 (addr: %p): %+8v\n",
    &s3, *(*reflect.SliceHeader)(unsafe.Pointer(&s3)))

输出(在 Go Playground 上尝试一下):

s1 (addr: 0x1040a130): {Data:       0 Len:       0 Cap:       0}
s2 (addr: 0x1040a140): {Data: 1535812 Len:       0 Cap:       0}
s3 (addr: 0x1040a150): {Data: 1535812 Len:       0 Cap:       0}

我们看到了什么?

  • 所有切片(切片头)都有不同的内存地址
  • nil 切片具有 0 数据指针
  • s2s3 切片确实具有相同的数据指针,共享/指向相同的 0 大小的内存值

以上就是Go 语言中 nil 切片、非 nil 切片、空切片的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: Go 语言中 nil 切片、非 nil 切片、空切片

本文链接: https://lsjlt.com/news/562052.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Go 语言中 nil 切片、非 nil 切片、空切片
    php小编小新为你带来了关于Go语言中的切片类型的介绍。在Go语言中,切片有三种状态:nil切片、非nil切片和空切片。这三种切片状态在使用时具有不同的含义和特点。了解这些切片类型的区...
    99+
    2024-02-08
    go语言
  • Go中的nil切片和空切片区别详解
    Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 ...
    99+
    2022-06-07
    nil GO
  • 切片与Go中的切片
    问题内容 在go中的unsafe.SliceData函数的文档中,它说: SliceData returns a pointer to the underlying array of...
    99+
    2024-02-06
  • 在go中重新切片2d切片
    一分耕耘,一分收获!既然打开了这篇文章《在go中重新切片2d切片》,就坚持看下去吧!文中内容包含等等知识点...希望你能在阅读本文后,能真真实实学到知识或者帮你解决心中的疑惑,也欢迎大佬或者新人朋友...
    99+
    2024-04-05
  • Go 切片
    切片 一、切片(slice)概念 在讲解切片(slice)之前,大家思考一下数组有什么问题? 数组定义完,长度是固定的。例如: var num [5]int = [5]int{1,2,3,4,5} 定义的num数组长度是5,表示只能存储5个...
    99+
    2023-08-30
    golang 开发语言
  • Go语言--切片(Slice)详解
    目录一、定义切片1、声明一个未指定大小的数组来定义切片2、使用make()函数来创建切片二、切片是可索引的1、len() 和 cap() 函数三、切片截取四、增加切片的容量说明: ...
    99+
    2024-04-02
  • go语言切片是什么
    go语言切片是对数组的一种抽象。切片是对数组的引用,包含了指向数组元素的指针、切片的长度和容量。创建切片的方式有:1、使用内置的make函数创建一个切片;2、使用切片的字面量创建一个切片;3、从另一个切片创建新的切片。可以使用内置的appe...
    99+
    2023-12-11
    Golang go语言
  • Go(3[切片])
    切片:切片底层都是数组切片是一个指针类型,是数组的引用!修改切片后的值,那原来的数据也会改变传输数据大的时候,使用切片,节省内存,因为底层只是对数组的引用append操作的适合,如果长度超过设置的长度,那底层就会把底层元组进行扩容切片里面可...
    99+
    2023-01-31
    切片
  • 聊聊go语言中的切片(slice)
    本篇文章带大家了解一下golang中可变长度的"数组"——切片(slice),希望对大家有所帮助!golang切片(slice)(1)切片的定义切片(Slice)是一个拥有相同类型元素的可变长度的序列。它是基于数组类型做...
    99+
    2022-07-04
    go语言 golang 切片
  • go语言切片怎么生成
    本篇内容介绍了“go语言切片怎么生成”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在go语言中,切片(slice)是对数组的一个连续片段的引...
    99+
    2023-07-04
  • go语言中的二维切片赋值
    先用append填充一维的,然后将一维append到二维 代码如下 var a [][]int for i := 0; i < 10; i++ { var t...
    99+
    2022-06-07
    GO 二维 赋值 go语言
  • go语言中切片如何加元素
    这篇文章主要介绍“go语言中切片如何加元素”,在日常操作中,相信很多人在go语言中切片如何加元素问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go语言中切片如何加元素”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-07-05
  • Go语言切片支持多维吗
    这篇文章主要介绍“Go语言切片支持多维吗”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Go语言切片支持多维吗”文章能帮助大家解决问题。可以。Go语言的切片是支持多维的,声明一个多维切片的语法格式“v...
    99+
    2023-07-05
  • Go语言copy()实现切片复制
    Go语言的内置函数 copy() 可以将一个数组切片复制到另一个数组切片中,如果加入的两个数组切片不一样大,就会按照其中较小的那个数组切片的元素个数进行复制。 copy() 函数的使...
    99+
    2023-05-14
    Go 切片复制 Go copy()
  • Go语言中的数组与切片介绍
    这篇文章主要讲解了“Go语言中的数组与切片介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Go语言中的数组与切片介绍”吧!1. 数组数组是一个由固定长度的...
    99+
    2024-04-02
  • go语言中切片如何增删元素
    这篇“go语言中切片如何增删元素”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“go语言中切片如何增删元素”文章吧。go语言中...
    99+
    2023-07-05
  • Go语言切片是怎么扩容的
    本篇内容主要讲解“Go语言切片是怎么扩容的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go语言切片是怎么扩容的”吧!在 Go 语言中,有一个很常用的数据结构,那就是切片(Slice)。切片是一...
    99+
    2023-07-06
  • Go 切片的用法
    问题内容 我正在查看 sha1 相关代码 https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/crypto/sha1...
    99+
    2024-02-05
  • Go 语言中怎么实现数组与切片
    本篇文章为大家展示了Go 语言中怎么实现数组与切片,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。数组数组是一组类型相同的,长度固定的,按数字编号排列的数据序列。由于 go  语言中,数组的...
    99+
    2023-06-15
  • Go语言中的数组和切片是什么
    本篇内容介绍了“Go语言中的数组和切片是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录 数组 切片(Slice)append 函数1...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作