栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Go语言中的nil切片vs非nil切片vs空切片

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Go语言中的nil切片vs非nil切片vs空切片

可观察的行为

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

  • 你可以将它们传递到内置
    len()
    cap()
    功能
  • 您可以
    for range
    在它们之上(将为0次迭代)
  • 您可以对其进行切片(不违反Spec:Slice表达式中概述的限制;因此结果也将为空切片)
  • 由于它们的长度为0,因此无法更改其内容(附加值将创建新的切片值)

请参见以下简单示例(一个

nil
切片和2个非
nil
空切片):

var s1 []int         // nil slices2 := []int{}        // non-nil, empty slices3 := make([]int, 0) // non-nil, empty slicefmt.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 [] trues2 0 0 false [] falses3 0 0 false [] false

(请注意,对切片进行

nil
切片会导致
nil
切片,对非
nil
切片进行切片会导致非
nil
切片。)

您只能通过将slice值与预先声明的标识符进行比较来区分差异

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 []ints2 := []int{}s3 := make([]int, 0)fmt.Printf("s1 (addr: %p): %+8vn",    &s1, *(*reflect.SliceHeader)(unsafe.Pointer(&s1)))fmt.Printf("s2 (addr: %p): %+8vn",    &s2, *(*reflect.SliceHeader)(unsafe.Pointer(&s2)))fmt.Printf("s3 (addr: %p): %+8vn",    &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
    slice具有相同的数据指针,共享/指向相同的0大小的内存值


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/426758.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号