go 的slice

slice初始化的表达式和初始化数组的表大式的区别:
slice字面上看去和数组字面量很像,都是用逗号分隔并用花括号括起来的一个元素序列,
但是slice没有指定长度。这种隐式区别的结果分别是创建具有固定的长度的数组和创建指定数组的slice。
和数组一样,slice也按照顺序指定元素,也可以通过索引来指定元素,或者两者结合。
和数组不同的是,slice无法做比较,因此不能用==来测试两个slice是否拥有相同的元素。
标准库里提供了bytes.Equal来做比较两个字节slice([]byte)。但是对其类型的slice,我们必须自己写函数来比较。

func equlaStringSlice(a,b []string) bool{
	if len(a) != len(b) {
		return false
	}

	for i:=range a {
		if a[i] != b[i]{
			return true
		}
	}
	return true
}

slice唯一允许的比较操作是和nil做比较
s := []string{}
if s == nil {}
slice类型的零值是nil。值为nil的slice没有对应的的底层数组。值为nil的slice长度和容量是零,但是也非nil的长度和容量都是0,
例如[]int{}make([]int,3).对于任何类型,如果它们的值可以是nil,那么这个类型的nil值可以使用一种转换表达式,例如[]int(nil)

var s []int  //len(s) == 0,s == nil 
s = nil //len(s) //len(s)==0,s == nil 
s =[]int(nil) //len(s) == 0, s== nil 
s = []int{} //len(s) == 0,s != nil 

所以如果想查件一个slice是否空,那么使用len(s) == 0,而不是s==nil,因为s!=nil情况下,slice也可能是空。


内置make函数可以创建一个具有指定元素类型,长度和容量的slice。其中容量参数可以省,在这种情况下,slice长度和容量相等。
make([]T,len)
make([]T,len,cap)
其实make创建了一个无名数组并返回了它的一个slice;这个数组仅可以通过个slice来访问。在上面的第一行代码中,所返回的slice引用了整个数组。
在第二行代码中,slice只引用了数组的前len个元素,但是它的容量是数组的长度。这为未来的slice元素留出空间。

func appendInt(x []int,y int) []int{

	var z []int
	zlen := len(x)+1
	if zlen <=cap(x){
		//slice仍有增长空间,扩展slice内容
		z = x[:zlen]
	}else{
		//slice已无空间,为它分配一个新的底层数组
		//为了达到分摊线性复杂性,容量扩展一倍
		zcap := zlen
		if zcap < 2 * len(x){
			zcap = 2 * len(x)
		}
		z = make([]int,zlen,zcap)
		copy(z,x) //内置copy函数
	}
	z[len(x)] = y
	return z
}


每一次appendInt调用都必须检查slice是否仍有足够容量来存储数组中的元素。
如果slice容量足够,那么它就会定义一个橷slice(仍然引用原始底层数组),然后将新的元素y复制到新的位置,并返回这个新的slice。输入参数slice x和函数返回值size z拥有相同的底层数组。
如果slice容量不够容纳增长的元素,appendInt函数必须创建一个拥有跢容量的新的底层数组来存储新的元素,然后将元素从slice x 复制到这个数组,再将新元素y追加到数组后面。返回值slice z将
和输入参数slice x引用不同的底层数组。
 

你可能感兴趣的:(golang编程学习)