说明
在Go语言中传入方法的参数都是值传递,值传递的也就是拷贝,也就是说传入的参数只在方法体内可以改变,外面不变,所以我们用到了指针,传入一个指针,就解决了值改变问题,因为指针* 代表引用传递,但是使用指针,很麻烦,因为每次都需要加上一个*(指针),而解决的方法又来了,那就是通过Slice(切片)解决这种问题!
Slice(切片的概念)
Slice本身是没有数据的,它是对底层array的一个View(视图),Slice可以向后扩展,但是不可以向前扩展,就像s[i]向后扩展不可以超越底层数组cap(s),但是可以超过len的长度
上代码
使用Slice(切片)
func updateSlice(a []int){
//给传入数组赋值
a[0] = 100;
}
func main(){
arr :=[...]int{0,1,2,3,4,5,6,7}
s:=arr[2:6];
fmt.println(s); s的值为:2,3,4,5
fmt.println("arr[2:6]=",arr[2:6]); 值:2,3,4,5 (从下标2到下标6(包2不包6)对应的值)
fmt.println("arr[2:]=",arr[2:]); 值:2,3,4,5,6,7(从下标2到数组最后一位的值)
fmt.println("arr[:6]=",arr[:6]); 值:0,1,2,3,4,5(从下标0到下标为6间的值)
fmt.println("arr[:]=",arr[:]); 值:0,1,2,3,4,5,6,7(数组全部)
s1:= arr[2:];
fmt.Println("arr[2:]",s1); 打印前arr[2:]的值为2,3,4,5,6,7
s2:= arr[:];
fmt.Println("After updateSlice(s1)");
updateSlice(s1); //经过切片,将下标为0的数据改为100
fmt.Println("arr[:]",s1); 经过切片后arr[:]的值为100,3,4,5,6,7
fmt.Println("arr",arr); 经过切片后arr[:]的值也改变为0,1,100,3,4,5,6,7
updateSlice(s2); //经过切片,将下标为0的数据改为100
fmt.Println("s2",s2); 经过切片后s2的值为,100,1,100,3,4,5,6,7
fmt.Println("arr",arr); 经过切片后arr的值为100,1,100,3,4,5,6,7
证明了Slice切片将值传递进去,即修改了s1和s2的值,也修改了原本数组的值
fmt.Println("Reslice");
fmt.Println("s2",s2);
s2 = s2[:5]; 得到s2前面的五个值100,1,100,3,4
s2 = s2[2:]; 得到s2下标从2开始到数组末尾的值
接下来是Slice(切片)的重点 arr2 :=[...]int{0,1,2,3,4,5,6,7} s3 := arr2[2:6]; 注意得到的是[2,3,4,5] s4 := s3[3:5]; 会得到什么呢?s3总长度为4,下标为4的值不存在,而下标为3到下标为5之间的值会得到什么?得到的是[5,6],这个时候有人会问了,为什么s3都没有对应的值,为什么还能变出来一个6,接下来上图让大家理解 一、最下面的代表arr数组的总体长度,0到7 二、s1也就是arr数组下标[2到6]代表获取到arr数组中[2,3,4,5]四个值,而2,3,4,5映射到s1的下标也就是[0,1,2,3],但因为s1是对底层arr的View(视图),所以下标不会停止在3,还有一个阴影的4和5,如果直接用s1[4]和s1[5]是看不见的,会出数组越界问题,但是系统是知道你有4和5两个值的,因为还是知道底层的arr的。 三、s2也就是arr[3:5]代表获取到arr数组下标为3到5之间的数据,取到了3,4,s2的下标此时是[0,1,2],因为s2下标对应到底层arr的值5,6,所以得到s2的值是5和6,从一个底层arr的view角度,就能理解为什么能取出来6 上图中是Slice的实现原理,首先要明白ptr是什么,len是什么,cap又是什么? ptr代表slice开头的元素,len代表slice的长度,使用[]只能取到len里面的值,当获取下标大于等于len的时候,就会产生下标越界了,cap代表整个arr的开始到结束的长度,只要长度不超过cap的长度,那么都可以扩展 要注意的是——s[i]不能超过len(s)的长度,向后扩展不能超过cap(s)的长度 Slice不是值类型(Go语言其余的都是值类型)(Slice肚子里有一个数据结构),Slice等同于一个视图,例如arr[2:6]就是看的arr的2到6,arr[:]看的则是arr的全部视图 这个s3和s4的len和cap也是可以获取的
fmt.println("s3=%v,s4=%v,len(s3)=%d,cap(s3)=%d\n",
s3,s4,len(s3),cap(s3);
);
得到的是——s3=[2 3 4 5],s4=[5 6],len(s3)=4,cap(s3)=6
这就是切片的基础概念和使用,后续会继续发布,如果有错误,我虚心请教,我也处于学习阶段,谢谢
}