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.

Trong Go, có một kiểu dữ liệu gọi là slice được xây dựng dựa trên mảng. Đây là một kiểu rất tiện lợi khi chúng ta muốn xử lý một nhóm dữ liệu. Bài viết này sẽ giải thích một sự khác biệt tinh tế nhưng phức tạp giữa empty slice (slice rỗng) và nil slice.

Một nil slice là một slice có độ dài và dung lượng bằng không và không có mảng cơ sở nào. Giá trị zero của slice là nil. Nếu một slice được khai báo như bên dưới, nó là một nil slice.

package main

import "fmt"

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

Kết quả đầu ra sẽ là true cho đoạn mã trên.

Một empty slice là một slice cũng có độ dài và dung lượng bằng không nhưng có mảng cơ sở với độ dài bằng không. Nếu một slice được khai báo như bên dưới, nó là một empty slice.

package main

import "fmt"

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

Kết quả đầu ra sẽ là false cho đoạn mã trên.

Một empty slice cũng có thể được tạo bằng hàm make().

package main

import "fmt"

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

Trong hầu hết các trường hợp, empty slice và nil slice có thể được coi là giống nhau. Chỉ trong một số trường hợp tinh tế, chúng nên được xử lý khác nhau, một trong số đó là khi thực hiện mã hóa JSON.

Một empty slice sẽ được mã hóa thành [] trong JSON trong khi nil slice sẽ được mã hóa thành 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":[]}

Điều này sẽ tạo ra một sự khác biệt lớn khi giá trị này được trả về dưới dạng phản hồi API. Front end cần phải xử lý điều này rất khác nhau. Nói chung, nil slice là một kiểu ưu tiên hơn.

JSON GOLANG EMPTY SLICE NIL SLICE

  RELATED

  COMMENTS

0

No comment for this article.