开发者学堂课程【Go 语言核心编程 - 基础语法、数组、切片、Map :切片注意事项和细节(1)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/625/detail/9640
切片注意事项和细节(1)
一、切片注意事项和细节讨论
1、切片初始化时 var slice = arr[startIndex:endIndex] (如果让一个切片直接引用一个已经存在的数组,它应该要有两个参数)
说明:从 arr 数组下标为 startlndex,取到下标为 endIndex 的元素(不含 arr[endIndex])。
2、切片初始化时,仍然不能越界。范围在[0-len(arr)]之间,但是可以动态增长。(在使用时,默认情况下这个切片按默认用法)
例如:
func main() {
//使用常规的for循环遍历切片
var arr [5]int = [...]int{10,20,30,40,50}
slice := arr[1:4] // 第四个元素没有取到,一共有三个元素,分别是20,30,40;
for i :=0; i < len(slice); i++ {
fmt.Printf("slice[%v]=%v ", i,slice[i])
}
fmt.Println() //使用for--range方式遍历切片
for i, v := range slice {
fmt.Printf(""i=%v v=%v \n", i,v)
}
fmt.Printf(slice[])
//因为只有三个元素,只能取0,1,2,;如果取到3,它便会报告越界
}
运行结果如下:
“index out of range”表示已越界;因为引用时没有引用到数组的最后一位元素,所以报错
(1) var slice = arr[0:end] 可以简写 var slice = arr[:end] //用一个切片去引用已经存在的数组,它有几种写法:例如 arr[0:end],如果起始的值为0,便可简写成arr[:end]
(2) var slice = arr[start:len(arr)] 可以简写: var slice = arr[start:] //如果起始是[start:len(arr)],也就是从起始位置取到末尾,一般情况下 len 是数组长度,而不包含数组长度就相当于把数组取完,所以这样便可以简写为 arr[start:]。后面的值便可不写,因为后面的值默认是数组的长度
(3) var slice = arr[0:len(arr)]可以简写:var slice = arr[:]
//如果默认把整个数组取下来,也就是需要一个切片把某个数组从第0个元素引用到它最后一个元素例如[0:len(arr)],便可以简写为 arr[:],其中 arr[:]第一个空默认是0,第二个空默认是 len(arr)
例如:
func main() {
//使用常规的for循环遍历切片
var arr [5]int = [...]int{10,20,30,40,50}
slice := arr[0:len(arr)] //取整个数组的元素
for i :=0; i < len(slice); i++ {
fmt.Printf("slice[%v]=%v ", i,slice[i])
}
fmt.Println() //使用for--range方式遍历切片
for i, v := range slice {
fmt.Printf("i=%v v=%v \n", i,v)
}
运行结果如下:
结果显示取出5个元素,所以这种写法(slice := arr[0:len(arr)])
也可以简写成 slice := arr[:],这样运行结果与之前一样
3、cap 是一个内置函数,用于统计切片的容量,即最大可以存放元素个数。
4、切片定义完后,还不能使用,因为本身是一个空的,需要让其引用到一个数组,或者 make 一个空间供切片来使用 //也就是定义完一个切片后,要么引用到一个数组里去,要么 make 一个空间来供切片使用,否则它是空的
5、切片可以继续切片
[案例演示]:func main( i
//使用常规的for循环遍历切片
var arr [5]int = [...]int{10,20,30,40,50}
slice := arr[1:4] //slice是一个切片,需要再切一块也可以
for i := e; i < len(slice); i++{
fmt.Printf("slice[%v]=%v ", i,slice[i])
}
fmt.Println()
//使用for--range方式遍历切片
for i, v := range slice {
fmt.Printf(i=%v v=x\n",i,v)
}
(1)slice2 := slice[1:2] //体现切片可以再次切片,从 slice 的第一个元素切到第二个元素;这时 slice2 也是一个切片,这样切相当于在原来切片基础上再切了一个元素出来,实际上就是20;因为原先 slice={10,20,30,40,50},然后从中切取下标为1切到下标为2 即是20;slice 和 slice2 都指向同一个数据空间;也就是说 slice2 改变了slice 也会同时变化,同时数组也会变化,因为他们都是引用类型的
运行结果如下:
//slice2 运行出来的元素是[20]
(2)如果将以上代码中 slice2 := slice[1:2]改为 slice2 := slice[2:4]那么取得元素则为[30,40]
(3)如果将以上代码中
将 slice := arr[:]改为 slice := arr[1:4]
那么这是 slice2 取多少?
首先找出 slice={20,30,40},然后找出 slice 中的第一个和第二个元素
运行结果如下:
(4) 如果 slice2[0]=100(slice2的第0个元素,将它改成100),请问 slice 和 arr 的数组是否会发生变化?
slice2[0] = 100 //不管是通过数组还是 slice 来看,都会变成100;因为 arr , slice 和 slice2 指向同一个数据空间,,因此 slice2[0]=100,其他的都变化
fmt.Println( "slice2=", slice2)
fmt.Println("slice=", slice)
fmt.Println("arr=", arr)
//现在输出的 slice2、slice、arr 对应的30都变成了100
}
运行结果如下: