tranche nulle, tranche non nulle, tranche vide en langage Go
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/ json
和 fmt
包)。
唯一的区别是将切片转换为数组指针(已添加到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
切片的容量和长度等于 0
、Len
和 Cap
字段,则很可能是 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
数据指针 -
s2
和s3
切片确实具有相同的数据指针,共享/指向相同的 0 大小的内存值
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

La bibliothèque utilisée pour le fonctionnement du numéro de point flottante dans le langage go présente comment s'assurer que la précision est ...

Problème de threading de file d'attente dans Go Crawler Colly explore le problème de l'utilisation de la bibliothèque Crawler Crawler dans le langage Go, les développeurs rencontrent souvent des problèmes avec les threads et les files d'attente de demande. � ...

Quelles bibliothèques de GO sont développées par de grandes entreprises ou des projets open source bien connus? Lors de la programmation en Go, les développeurs rencontrent souvent des besoins communs, ...

Deux façons de définir les structures dans le langage GO: la différence entre les mots clés VAR et le type. Lorsque vous définissez des structures, GO Language voit souvent deux façons d'écrire différentes: d'abord ...

Le problème de l'utilisation de Redessstream pour implémenter les files d'attente de messages dans le langage GO consiste à utiliser le langage GO et redis ...

La différence entre l'impression de chaîne dans le langage go: la différence dans l'effet de l'utilisation de fonctions println et string () est en Go ...

GO POINTER SYNTAXE ET ATTENDRE DES PROBLÈMES DANS LA BIBLIOTHÈQUE VIPER Lors de la programmation en langage Go, il est crucial de comprendre la syntaxe et l'utilisation des pointeurs, en particulier dans ...

Pourquoi l'itération de la carte dans GO fait-elle que toutes les valeurs deviennent le dernier élément? En langue go, face à des questions d'entrevue, vous rencontrez souvent des cartes ...
