【面试题】slice := make([]string, 0, len(A))和slice := []string{}的区别

210 阅读2分钟

先看这四个语句

slice := make([]string, 0, len(A))
slice := make([]string, len(A))
slice := make([]string, 0)
slice := []string{}  

这四个有什么区别

slice := make([]string, 0, len(A))

这个语句创建了一个长度为0的字符串切片,并且为其分配了一个初始容量为len(A)的底层数组。这意味着该切片可以容纳len(A)个元素,但是初始时没有任何元素。

例如:

A := []string{"apple", "banana", "cherry"}
slice := make([]string, 0, len(A))
fmt.Println(slice)         // []
fmt.Println(len(slice))    // 输出:0
fmt.Println(cap(slice))    // 输出:3

slice := make([]string, len(A))

这个语句创建了一个长度为 len(A) 的字符串切片,并且为其分配了一个底层数组。切片的容量与长度相同,因此它可以容纳 len(A) 个元素。

与 slice := make([]string, 0, len(A)) 不同,这个语句创建的切片的长度不是0,而是 len(A)。这意味着切片已经预留了足够的空间来存储 len(A) 个元素,而不需要进行动态扩容。

注意 这个语句只是创建了一个长度为 len(A) 的切片,但是切片中的元素仍然是零值(对于字符串切片来说,零值是空字符串 "")。如果需要给切片赋值具体的元素,可以使用切片索引的方式进行赋值。

例如:

A := []string{"apple", "banana", "cherry"}
slice := make([]string, len(A))
fmt.Println(slice)         // ["","",""]
fmt.Println(len(slice))    // 输出:3
fmt.Println(cap(slice))    // 输出:3

slice := make([]string, 0)

这个语句创建了一个长度为0的字符串切片,并且没有为其分配任何底层数组。这意味着该切片没有任何容量,不能存储任何元素。

例如:

slice := make([]string, 0)
fmt.Println(slice)         // []
fmt.Println(len(slice))    // 输出:0
fmt.Println(cap(slice))    // 输出:0

slice := []string{}

这个语句使用了切片字面量的方式创建了一个长度为0的字符串切片。它相当于使用了make([]string, 0)。 例如:

slice := []string{}
fmt.Println(len(slice))    // 输出:0
fmt.Println(cap(slice))    // 输出:0

综上所述,区别主要在于切片的容量和是否分配底层数组。第一个语句分配了一个具有一定容量的底层数组,第二个创建长度为len(A)的字符串切片,分配底层数组,容量与长度相同。第三个语句没有分配底层数组,第四个语句相当于第二个语句的简写形式。