Go - 24 Go 切片

切片的基本介绍
        在不确定个数的多少的情况下,我就不能使用固定长度的数组了    
        1.切片的英文slice
        2.切片是数组的一个引用,因此切片是引用数据类型,在进行传递时,遵守引用传递的机制;
        3.切片的使用和数组类似,遍历切片,访问切片的元素和求切片长度len(slice) 都一样;
        4.切片的长度是可以变化的,因此切片是一个可以动态变化的数组
        5.切片定义的基本语法:
                var 切片名  []类型
                示例:var  a []int 
        切片在内存中的形式:(重要)
            1.切片底层的数据结构可以理解成是一个结构体struct(ptr,len,cap)
            2.输出切片和切片的引用地址;
    切片的使用:
        三种方式:
            第一种:定义一个切片,然后让切片去引用一个已经创建好的数组;
            第二种:通过make来创建切片;
                基本语法:
                        var  切片名  []type  = make([], len, [cap])
                        参数说明:type:数据类型,len:大小,cap:指定切片容量,可选
                示例:
                    var slice_1 []int = make([]int, 4, 20)  // 需要使用 make     
                    // 输出 [0 0 0 0] 4 20     
                    fmt.Println(slice_1, len(slice_1), cap(slice_1))     
                    slice_1[2] = 20     
                    slice_1[0] = 10     
                    fmt.Println(slice_1)  // [10 0 20 0]
                使用make 创建的话,对应数组在底层只能通过slice 来访问和修改,对外不可见,区别于第一种方式,第一种方式可以通过数组也可以通过切片来访问;
            第三种方式:var  stringslice []string = []string{"tom", "jack", "marry"}
                    示例:
                        var  stringslice []string = []string{"tom", "jack", "marry"}    
                        fmt.Println(stringslice, len(stringslice), cap(stringslice))   // [tom jack marry] 3 3
        方式一和方式二之间的区别:
                1.方式一,是直接引用数组,这个数组是事先存在的,程序员是可见的;
                2.方式二,是通过make来创建切片,make也会创建一个数组,是由切片在底层进行维护,程序员是看不见的;
            
        切片的遍历:和数组进本一样没有什么特别注意的地方;
            第一种:常规的方式;
            第二种:for-range:
        
        切片注意的事项和细节说明:
            1.切片初始化时,var  slice = arr[startindex:endindex]
            说明:从arr数组下标为startindex, 取到下标为endindex的元素 不含 arr[endindex];
            2.切片初始化时,任然不能越界,范围在 [0-len(arr)] 之间,但是可以动态增长;
                var slice =  arr[0:end] 可以简写 var  slice = arr[:end]
                var slice = arr[start:len(arr)] 可以简写:var slice = arr[start:]
                var slice = arr[0:len(arr)] 可以简写:var slice = arr[:]
            3.cap是一个内置函数,用于统计切片的容量,即最大可以存放多少个元素;
            4.切片定义完后,还不能使用,因为本身是一个空的,需要让其引用到一个数组,或者make一个空间供切片使用;
           5. 切片可以继续切片;
            6.用append内置函数,可以对切片进行动态追加
                底层原理分析:
                切片append操作的本质就是对数组扩容;
                go底层会创建一个新的数组newArr
                将slice原来包含的元素拷贝到新的数组newArr
                slice重新引用到newArr
                注意newArr是在底层来维护的,程序员不可见;
            7.切片拷贝的操作;
                copy[para1, para2] --> para1 和para2 都是切片类型;不管para1 和 para2 的长度只赋值对应位置的数值;切片是引用类型,所以在传递时,遵守引用传递机制;
 
    string和slice:
            1.string在底层是一个byte数组,因此string可以进行切片处理;
            2.string和切片在内存的形式一样,都是引用数组,但是不能通过 str[0] = 'z' , 因为str是不可变的
            3.如果想修改字符串中的字符,可以先转成 []byte 切片,改完后再转为字符串;(可以处理英文和数字,汉字会乱码)
                如果想解决中文乱码问题可以通过 转成 []rune 切片即可,因为[]rune 是按字符处理,兼容汉字
                示例:
                    str_1 := "hello@atguigu"    
                    byte_arr := []rune(str_1)     
                    // byte_arr[0] = 'g'  // str_1== gello@atguigu     
                    byte_arr[0] = '北'  // str_1== 北ello@atguigu     
                    str_1 = string(byte_arr)     
                    fmt.Println("str_1==", str_1)  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2020-11-18 14:49  以赛亚  阅读(117)  评论(0编辑  收藏  举报