Go中的片断可以由3个元素表示。
ptr- 一个指向底层数组的指针,包含了该片的数据len- 长度,分片中的元素数cap- 容量,底层数据数组中的元素数,从""指向的元素开始。ptr
一个声明为var s1 []string 的nil slice没有底层数据数组--它没有指向任何东西。一个声明为s2 := []string{} 或s3 := make([]string, 0) 的空片子指向一个空的、非零的数组。
也请详细了解切片的长度和容量有什么区别
参见表格来比较nil 和空片的属性。
| ptr | 长度 | cap | |
|---|---|---|---|
nil:[]string | 0 | 0 | 0 |
空。[]string{} | <地址 | 0 | 0 |
空的。make([]string, 0) | <地址 | 0 | 0 |
<addr> ,是一个非零的地址,指向一个空的、非零的阵列。
package main
import "fmt"
func main() {
var s1 []string // nil
s2 := []string{} // empty
s3 := make([]string, 0) // empty, equivalent to s2 := []string{}
fmt.Printf("s1 is nil: %t, len: %d, cap: %d\n", s1 == nil, len(s1), cap(s1))
fmt.Printf("s2 is nil: %t, len: %d, cap: %d\n", s2 == nil, len(s2), cap(s2))
fmt.Printf("s3 is nil: %t, len: %d, cap: %d\n", s3 == nil, len(s3), cap(s3))
}
输出。
s1 is nil: true, len: 0, cap: 0
s2 is nil: false, len: 0, cap: 0
s3 is nil: false, len: 0, cap: 0
空片和nil 片的行为是一样的,就是内置函数如len(),cap(),append(), 和for .. range 循环返回同样的结果。因此,由于nil slice声明更简单,你应该更喜欢它而不是创建一个空slice。然而,在某些情况下,你可能需要空的、非零的片断。例如,当你想返回一个空的JSON数组[] 作为HTTP响应时,你应该创建空的分片([]string{} 或make([]string, 0) ),因为如果你使用nil 分片,在编码后你会得到一个null JSON数组。
package main
import (
"encoding/json"
"fmt"
"log"
)
func main() {
var s1 []string // nil
s2 := []string{} // empty
s3 := make([]string, 0) // empty, equivalent to s2 := []string{}
s1JSON, err := json.Marshal(s1)
if err != nil {
log.Fatal(err)
}
fmt.Printf("s1 JSON: %s\n", string(s1JSON))
s2JSON, err := json.Marshal(s2)
if err != nil {
log.Fatal(err)
}
fmt.Printf("s2 JSON: %s\n", string(s2JSON))
s3JSON, err := json.Marshal(s3)
if err != nil {
log.Fatal(err)
}
fmt.Printf("s3 JSON: %s\n", string(s3JSON))
}
输出。
s1 JSON: null
s2 JSON: []
s3 JSON: []