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 ซึ่งสร้างขึ้นบน array มันเป็นชนิดข้อมูลที่สะดวกมากเมื่อเราต้องการจัดการกับกลุ่มข้อมูล โพสต์นี้จะอธิบายความแตกต่างที่ละเอียดอ่อนแต่ซับซ้อนระหว่าง empty slice และ nil slice

Nil slice คือ slice ที่มีความยาวและความจุเป็นศูนย์ และไม่มี array รองรับ ค่าศูนย์ของ slice คือ nil ถ้า slice ถูกประกาศดังต่อไปนี้ มันคือ nil slice

package main

import "fmt"

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

ผลลัพธ์จะเป็น true สำหรับโค้ดข้างต้น 

Empty slice คือ slice ที่มีความยาวและความจุเป็นศูนย์เช่นกัน แต่มี array รองรับที่มีความยาวเป็นศูนย์ ถ้า slice ถูกประกาศดังต่อไปนี้ มันคือ empty slice

package main

import "fmt"

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

ผลลัพธ์จะเป็น false สำหรับโค้ดข้างต้น

Empty slice สามารถสร้างได้ด้วยฟังก์ชัน make()

package main

import "fmt"

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

ในกรณีส่วนใหญ่ empty slice และ nil slice สามารถใช้เหมือนกันได้ เฉพาะในบางกรณีที่ละเอียดอ่อนเท่านั้นที่ควรปฏิบัติต่อต่างกัน หนึ่งในนั้นคือเมื่อทำการเข้ารหัส JSON

Empty slice จะถูกเข้ารหัสเป็น [] ใน JSON ในขณะที่ nil slice จะถูกเข้ารหัสเป็น 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 Front end ต้องปฏิบัติต่อสิ่งนี้แตกต่างกันมาก โดยทั่วไป nil slice เป็นรูปแบบที่ต้องการ

JSON GOLANG EMPTY SLICE NIL SLICE

  RELATED

  COMMENTS

0

No comment for this article.