Empty slice vs nil slice in GoLang

English 简体中文 繁体中文 ภาษาไทย Tiếng Việt
Summary

Go's slice type presents a subtle but important distinction between nil and empty slices, even though both have zero length and capacity. A nil slice, which is the zero value for a slice, lacks an underlying array and evaluates as `nil`, typically declared with `var s []T`. Conversely, an empty slice, created using `[]T{}` or `make([]T, 0)`, possesses a zero-length underlying array and does not evaluate as `nil`. This difference is particularly critical during JSON encoding, where a nil slice marshals to `null` while an empty slice marshals to `[]`, significantly impacting API responses and frontend data handling. Therefore, understanding this behavior is essential, with nil slices generally being the preferred style.

在 Go 语言中,有一种叫做 slice(切片)的类型,它构建于数组之上。当我们想要处理一组数据时,这是一种非常方便的类型。这篇文章将解释 空切片(empty slice)nil 切片(nil slice)之间一个微妙但棘手的区别。

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

package main

import "fmt"

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

对于上面的代码片段,输出将是 true

一个 空切片 是指长度和容量也为零,但具有长度为零的底层数组的切片。如果一个切片像下面这样声明,它就是一个空切片。

package main

import "fmt"

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

对于上面的代码片段,输出将是 false

也可以使用 make() 函数创建一个空切片。

package main

import "fmt"

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

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

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

package main

import (
  "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 切片是一种更受欢迎的风格。

JSON GOLANG EMPTY SLICE NIL SLICE

  RELATED

  COMMENTS

0

No comment for this article.