go_slice相关知识
①切片的左闭右开的引用
var s = [...]string{"a", "b", "c", "d", "e"}
fmt.Printf("%T\f%q\f%d\n", s, s, len(s))
a := s[0:4] //i=0,j=4,a切片实际上引用了s数组中的从i到j-1索引位置的元素==左闭右开的引用
fmt.Printf("%T\f%q\f%d\f%d\n", a, a, len(a), cap(a))
②切片的引用超过引用对象的容量会宕机;超过引用长度的容量会扩展长度
b := s[:]
fmt.Printf("%T\f%q\f%d\f%d\n", b, b, len(b), cap(b))
③对于string和[]byte的切片操作返回的分别是string和[]byte
c := "hello, world"
d := c[:len(c)]
fmt.Printf("%T,%q,%d\n", d, d, len(d))
e := []byte{'a', 'b', 'c'}
fmt.Printf("%T,%[1]q,len:%d,cap:%d\n", e, len(e), cap(e))
f := e[:1]
fmt.Printf("%T,%[1]q,len:%d,cap:%d\n", f, len(f), cap(f))
④切片可以作为函数的参数从而修改底层数组的元素
⑤数组可以比较,切片不能比较(但可以自己写函数来比较)
h := func(x, y []string) bool {
if len(x) != len(y) {
return false
}
//遍历x,y中相同索引所代表的元素
for i := range x {
if x[i] != y[i] {
return false
}
}
return true
}(a, b)
fmt.Println(h)
⑥切片唯一允许与nil比较,值为nil的切片没有对应的底层数组
i := []int{}
fmt.Printf("%d,%t\n", len(i), i == nil) //len(i)=0,i!=nil
i = nil
fmt.Printf("%d,%t\n", len(i), i == nil) //len(i)=0,i=nil
//所以使用len(i)==0,而不是s==nil来判断一个切片是否为空,因为在i!=nil的情况下,切片也可能为空。slice==nil一定为空
⑦用make函数创建一个无名数组并返回它的一个切片,这个数组只能通过该切片访问
j := make([]string, 5, 5)
fmt.Printf("%T,%[1]v,%t\n", j, j == nil)
⑧用append函数来为切片追加元素
var k []string
for _, value := range "who's your dad?" {
k = append(k, string(value))
}
fmt.Printf("%q\n",k)
//我们无法确定调用append函数后的结果切片是否指向同一个底层数组
//通常通过对调用结果再次赋值来确保对旧切片上的操作不会影响新的切片元素
//将其推广,对于任何函数,只要有可能改变切片的长度或者容量,或使切片指向不同的底层数组,都需要更新切片变量