ใน 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 เป็นรูปแบบที่ต้องการ