Go语言Slice(切片)

说明

        在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
这就是切片的基础概念和使用,后续会继续发布,如果有错误,我虚心请教,我也处于学习阶段,谢谢   

}


  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值