赞
踩
Golang中的切片是对数组的抽象和封装,切片的长度和容量不是固定的,是可以动态增加的
var mySlice []int
mySlice1 := []int{1, 2, 3}
fmt.Println(mySlice1)
这里和数组的区别很明显的是数组只需要在[]里面填个值就成了数组,不填,则是切片
与Python相同,切片可以进行切片操作
Slice[startIndex : endIndex] 将返回一个新切片
sl1 := mySlice1[0 : len(mySlice1)-1]
fmt.Println(sl1) // [1 2]
sl1 := mySlice1[0 : len(mySlice1)]
fmt.Println(sl1) // [1 2 3]
注意:这里的endIndex是不包含最后一个索引的,即如果是Slice[i, j],实际上返回的数据是(i, j-1),如 mySlice1[0: 2] 实际返回 [1,2]
如果需要包括最后一个数值,需要在其基础上+1,但是不能超过切片本身的长度,否则会报错
// panic: runtime error: slice bounds out of range [:4] with capacity 3
sl1 = mySlice1[0:4]
sl1 = mySlice[: 3] // sl1 = mySlice[0: 3]
sl1 = mySlice[2:] // sl1 = mySlice[2: len(mySlice)]
如上所示
每个切片的底层都是一个数组,切片仅仅是这个底层数组的一个视图
当使用make或字面量创建切片的时候,底层数组会被自动的创建出来。
下面的代码很有意思,可以让我们加深切片的理解
// 声明和初始化一个数组
arr := [5]int{1, 2, 3, 4, 5}
sl1 = arr[:3] // sl1切片由该数组而来
sl2 := arr[0:]
fmt.Println(sl1)
fmt.Println(sl2)
sl1[0] = 6 // 修改切片的第1个值
fmt.Println(sl1) //
fmt.Println(arr) // arr的值也被修改
fmt.Println(sl2) // sl2的值也被修改
由于上述的实验, 我们应该用切片字面量和make来创建切片,而不是像上面这样基于数组。避免修改了切片的值会影响到原来的数组
apppend将返回一个和原切片完全相同并且尾部追加新元素的新切片。
这个新切片与原切片不同的底层数组。当append发生在原数组地址空间无法扩展时,将重新开辟一块内存,把当前的元素全部拷贝过去,再在尾部追加新元素。而这一切都是append内部发生的,所以无法确定新切片是否和老切片共享底层数组。
因此我们在append以后需要把新切片赋值给原来的切片,这样就比较安全。
sl3 := append(sl1, 4, 5) // 危险,sl3和sl1不确定是否互相影响
sl1 := append(sl1, 4, 5) // OK,还是sl1上操作
与数组一样,如果访问了一个未赋值的切片,则会得到它的0值
// 声明一个切片
var declearSlice []int
// 打印decleareClice的原始状态
fmt.Printf("declear clice %#v\n", declearSlice)
// 可以直接append给nil的切片
declearSlice = append(declearSlice, 1)
// 再次打印该切片
fmt.Printf("declear clice %#v\n", declearSlice)
fmt.Println(len(declearSlice))
运行结果如下
declear clice []int(nil)
declear clice []int{1}
1
以上的实验说明go对切片进行了特殊处理,即使是nil切片也可以正常append操作
但是如果是赋值,则会发生panic
var dSlice []int
dSlice[0] = 1 // runtime error: index out of range [0] with length 0
所以append是安全的,但赋值是危险的,必须要判断该切片长度是否达标。
当我们运行程序时,主函数main是没有参数的,但是操作系统会把参数以切片的形式带过来,在golang中叫做os.Args
for index, value := range os.Args {
fmt.Println(index, value)
}
go run main.go first second
执行上面的代码后,我们可以得到以下的结果
0 C:\Users\ADMINI~1\AppData\Local\Temp\go-build4120744967\b001\exe\main.exe
1 first
2 second
第一个元素是程序的名称,我们从第2个元素开始取,则能得到我们自定义的参数
for index, value := range os.Args {
if index == 0 {
continue
}
fmt.Println(index, value)
}
修改一下代码,我们则可以看到只有
1 first
2 second
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。