为了账号安全,请及时绑定邮箱和手机立即绑定

切片的零值不为零

切片的零值不为零

Go
呼唤远方 2021-10-18 09:56:40
我正在遵循示例https://tour.golang.org/moretypes/10 我修改了代码,希望得到相同的结果。我没有。这是错误还是文档错误?巡演说一个 nil 切片的长度和容量为 0。我的 y 变量的长度和容量为 0。package mainimport "fmt"func myPrint(z []int) {    fmt.Println(z, len(z), cap(z))    if z == nil {        fmt.Println("nil!")    }}func main() {    var z  []int     y := []int {}    myPrint(z)    myPrint(y)}这是我的输出。[] 0 0nil![] 0 0我期待第二个“零”~为什么我没有得到它?
查看完整描述

3 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

nil与empty切片

如果我们考虑这样的切片:


[pointer] [length] [capacity]

然后:


nil slice:   [nil][0][0]

empty slice: [addr][0][0] // it points to an address

来自:“行动起来”一书:


零切片

当您想要表示一个不存在的切片时,它们很有用,例如在返回切片的函数中发生异常时。


// Create a nil slice of integers.

var slice []int

空切片

当您想要表示一个空集合时,例如当数据库查询返回零结果时,空切片很有用。


// Use make to create an empty slice of integers.

slice := make([]int, 0)


// Use a slice literal to create an empty slice of integers.

slice := []int{}

👉不管您使用的是零片或空片,内置的功能append,len和cap工作一样。


去游乐场示例:


package main


import (

    "fmt"

)


func main() {


    var nil_slice []int

    var empty_slice = []int{}


    fmt.Println(nil_slice == nil, len(nil_slice), cap(nil_slice))

    fmt.Println(empty_slice == nil, len(empty_slice), cap(empty_slice))


}

印刷:


true 0 0

false 0 0


查看完整回答
反对 回复 2021-10-18
?
潇湘沐

TA贡献1816条经验 获得超6个赞

您引用的文档指出nil 切片的长度和容量为 0,但并非每个长度和容量为零的切片都是 nil 切片。规范只说未初始化的切片的值为 nil。


这是支持len和cap未初始化(nil)切片的便利。否则我们需要先检查非 nil 以避免恐慌。(这也适用于其他内置类型,如地图或通道。)


在fmt.Print输出方面,行为的差异类似于打印未初始化(nil)指针与指向空结构的指针:


var s *struct{} // uninitialised pointer

fmt.Println(s)  // <nil>


s = &struct{}{} // pointer to an empty structure

fmt.Println(s)  // &{}


查看完整回答
反对 回复 2021-10-18
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

在这种情况下:

var z []int

您已经声明了一个变量,z但没有对其进行初始化。

在这种情况下:

y := []int {}

你声明并初始化它,你将它设置为一个空切片。把第二个表达式写得很长,这两个表达式之间的区别就更清楚了:

var y []int = []int {}


查看完整回答
反对 回复 2021-10-18
  • 3 回答
  • 0 关注
  • 244 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信