探索GoLang:空切片与nil切片的对比

发表时间: 2023-11-29 15:23

在Go中,有一种类型称为切片(slice),它是建立在数组之上的。当我们想要处理一组数据时,它是一种非常方便的类型。本文将解释空切片和nil切片之间微妙但棘手的区别。

一个nil切片是长度和容量都为零且没有底层数组的切片。切片的零值是nil。如果一个切片声明如下,那它就是一个nil切片。

package mainimport "fmt"func main() {	var a []string	fmt.Println(a == nil)}

上述代码片段的输出将为true。

一个空切片也是长度和容量都为零但具有底层数组且长度为零的切片。如果一个切片声明如下,那它就是一个空切片。

package mainimport "fmt"func main() {	b := []string{}	fmt.Println(b == nil)}

上述代码片段的输出将为false。

空切片还可以使用make()函数创建

package mainimport "fmt"func main() {	c := make([]string, 0)	fmt.Println(c == nil)}

在大多数情况下,空切片和nil切片可以被视为相同。只有在一些微妙的情况下,它们应该被区别对待,其中之一是在进行JSON编码时。

一个空切片将被编码为JSON中的[],而nil切片将被编码为null。

package mainimport (  "fmt"  "encoding/json")type A struct {	Data []string}func main() {	var a []string	fmt.Println(a == nil)		as := &A{		Data: a,	}	aj, _ := json.Marshal(as)	fmt.Printf("%s\n", string(aj))		b := []string{}	fmt.Println(b == nil)		bs := &A{		Data: b,	}	bj, _ := json.Marshal(bs)	fmt.Printf("%s\n", string(bj))}// true// {"Data":null}// false// {"Data":[]}

当这个值作为API响应返回时,这将产生很大的差异。前端需要以非常不同的方式处理这个差异。一般来说,nil切片是一种更受欢迎的风格。

翻译自Empty slice vs nil slice in GoLang | Pixelstech.net