Go(3[切片])

发布时间:2019-09-21 11:01:35编辑:auto阅读(1644)

    切片:

    • 切片底层都是数组

    • 切片是一个指针类型,是数组的引用!

    • 修改切片后的值,那原来的数据也会改变

    • 传输数据大的时候,使用切片,节省内存,因为底层只是对数组的引用

    • append操作的适合,如果长度超过设置的长度,那底层就会把底层元组进行扩容

    • 切片里面可以放任何类型!!!

    切片初始化:

        var b[]int = []int{1,2,3,4,5}

    • 切片底层都是数组

    • 切片是一个指针类型,应用类型,是数组的引用!!!

    • 修改切片后的值,那原来的数据也会改变

    • 如果传输的内容过大,介意用切片,节省内存

    切片定义(代码):

        切片是数组的引用,所以先创建一个数组

        var a [5]int

        var b[]int = a[0:2]       b是切片    

    伪代码定义:

        a[start:end]

    示例

    1. 示例一: 循环数组

      1. 时刻记住go是强类型语言,变量后面需要指定类型

      2. func Sum(a [100]int)int  {
           c:=0
           for i:=0;i<len(a);i++{
              c += a[i]
           }
           return c
        }


    2. 示例二:循环切片

      1. 其实与循环数组方式一样

      2. 需要注意是传参的时候,需要把数组转化为切片

        1. var c[1000] int  转化为切片就是 c[:]

      3. func Sum2(a []int)int  {
           c:=0
           for i:=0;i<len(a);i++{
              c += a[i]
           }
           return c
        }


    字符串切片:

    //一个bytes占一个字节  一个字节是8位
    //一个字符--》有可能占一个字节,或者三个字节
    //一个中文,占3个字节

    字符串底层是bytes的切片,   是用指针指向utf-8字节数组!!

    字符串是只读的!!,所以需要把字符串转切片,然后在修改字符串,那就相当于开辟一块新的内存空间

    修改字符串,可将其转化成【】rune或[]bytes ,完成后在转化为string ,无论哪种方式,都会重新分配内存,并复制字节数组

    var str = "hello word"
    //把字符串转切片,然后在修改字符串
    str1 := str[:]
    fmt.Printf("%s\n",str1)
    //单引号是代表一个字符
    var b []byte = []byte(str)
    //通过下标重新赋值
    b[0] = 'a'
    str2 := string(b)
    fmt.Println(str2,len(b))

    示例一:

    func testRever()  {
       //英文反转
       var str = "hello word"
       var b []byte = []byte(str)
       for i:=0;i< len(b) /2 ;i++{
          b[i] = b[len(b) -i -1]
          b[len(b) -i -1] = b[i]
    
       }
       str2 := string(b)
       fmt.Println(str2,len(b))
    }

    实例二:

    中文操作:rune 

    func testChina()  {
       //带中文的反转
       str :="Hi  我爱晨红"
       //rune 可能占一个字节或者多个字节
       b :=[]rune(str)
       fmt.Println("testChina",len(str),len(b))
       for i:=0;i< len(b) /2 ;i++{
          b[i],b[len(b) -i -1] = b[len(b) -i -1],b[i]
       }
       str2 := string(b)
       fmt.Println("testChina",str2)
    }
    func testConetChine()  {
       //统计中文,和英文出现的次数
       str :="翟hello,worker"
       b :=[]rune(str)
       fmt.Println("testChina",len(str),len(b))
    }
    
    >>>>testChina 17 13

    得出!!当统计类型为字符串的适合,它会把每个值都当成一个字节来统计

        转换rune后,那统计rune后的值,长度就变化了

    实例三:

    func testConetChine()  {
       //统计中文,和英文出现的次数
       str :="哈哈哈哈测试,hello,worker"
       b :=[]rune(str)
       fmt.Println("testChina",len(b),len(str))
    
    }

    切片的创建:

    1. 第一种定义方式:定义切片的时候.默认是空 nil

      1. var a[]int
        a = append(a,1,2,3,7,8)
        fmt.Printf("%#v\n",a)
    2. 第二种定义方式:用make的时候,切片内容默认都是0,底层是有数据的
      1. a=make([]int,5)
        a = append(a,1,2,3,7,8)
        fmt.Printf("%#v\n",a)
    • 切片只能用make来创建

    • 底层还是数组,是make来创建的

    • //容量扩容原理

      • 示例:

        • func testSliceCap()  {
          
             //a切片长度为5,容量为10,那底层数组长度就是10
             //那b 可以在a的基础上扩容, 但是不能超容量10
             a := make([]int,5,10)
             a[4] = 100
             //容量是从1开始,所以现在 b:=a[1:3] 的容量是9
             b:=a[1:3]
             //b[9] = 100
          
             fmt.Printf("a=%#v\n",a)
             fmt.Printf("b=%#v\n",b)
             //cap 内置方法 求出切片的容量7
             fmt.Println(cap(a),cap(b))
          }

    切片Copy:

        copy(目标切片,源切片) 

    1. 打印内存地址参数:p

    2. cap 切片容量

    s1 :=[]int{1,2,3}
    s2 :=make([]int,10)
    copy(s2,s1)
    fmt.Println("\n",s1)
    fmt.Println("\n",s2,cap(s2))
    
    >------
     [1 2 3]
    
     [1 2 3 0 0 0 0 0 0 0] 10

    切片Append:


    定义切片: s3 :=[]int{1,2,3}

    s4:=append(s3,3,4,5,6)


    数组 / 切片 中的 ... 使用

    数组:

    func testArray()  {
       var a [5]int = [5]int{1,3}
       fmt.Println(a)
       //数组的...  是系统内部帮你计算,当你不知道有多少个的时候,那就用...
       var c  = [...]int{1,3,4}
       fmt.Println(c)
    }

    切片:

    2个切片的append

    //... 就是展开切片的意思

    a = make([]int,5)
    var b[] = []int{1,3,6,10}
    a = append(a,b...)



关键字