zoukankan      html  css  js  c++  java
  • 数组和切片4

    切片的遍历:

    切片的遍历和数组一样,也有两种方式

      1)for 循环常规方式遍历

      2)for-range 结构遍历切片


    两种方式都在下面的代码里:

    案例演示:

    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 ", i, v)
      }
    }

    切片的注意事项和细节说明:

    切片初始化时 var slice = arr[startIndex:endIndex]
    说明:从arr 数组下标为startIndex,取到下标为endIndex的元素,不含arr[endIndex]。

    切片初始化时,仍然不能越界。范围在 [0-len(arr)] 之间,但是可以动态增长。

      1)var slice = arr[0:end] 可以简写 var slice = arr[:end]
      2)var slice = arr[start:len(arr)] 可以简写: var slice = arr[start:]
      3)var slice = arr[0:len(arr)] 可以简写: var slice = arr[:]


    cap是一个内置函数,用于统计切片的容量,即最大可以存放多少个元素。

    切片定义完后,还不能使用,因为本身是一个空的,需要让其引用到一个数组,或者make一个空间供切片来使用

    切片可以继续切片

    用append内置函数,可对切片进行动态追加

    func main() {

      //用append内置函数,可以对切片进行动态追加

      var slice3 = []int{100, 200, 300}

      //通过append直接给slice3追加具体的元素

      slice3 = append(slice3, 400, 500, 600)

      //通过append将切片slice3追加给slice3

      slice3 = append(slice3, slice3...)

      fmt.Println("slice3=", slice3)
    }

    切片append操作的底层原理分析:

      1)切片append操作的本质就是对数组扩容

      2)go底层会创建一个新的数组newArr(按照扩容后大小)

      3)将slice原来包含的元素拷贝到新的数组newArr

      4)slice重新引用到newArr

      5)注意newArr是在底层来维护的,程序员不可见

      6)案例演示说明:

    切片的拷贝操作:

    切片使用copy内置函数完成拷贝,举例说明:

    func main() {

      var slice4 []int = []int {1,2,3,4,5}
      var slice5 = make([]int, 10)
      copy(slice5, slice4)
      fmt.Println("slice4=", slice4)
      fmt.Println("slice5=", slice5)
    }


    对上面代码的说明:

    (1)copy(para1, para2):参数的数据类型都是切片类型。

    (2)按照上面的代码来看,slice4和slice5的数据空间是独立的,相互不影响,也就是说 slice4[0]=999,slice5[0] 仍然是1。


    思考题:下面的代码有没有错误:

    var a []int = []int {1,2,3,4,5}
    var slice = make([]int, 1)
    fmt.Println(slice)   //0
    copy(slice, a)   //这里是不会报长度不够这个错的,虽然长度只有1。长度有多大,就拷贝几个值过来
    fmt.Println(slice)   //1

    说明:上面的代码没有问题,可以运行,最后输出的结果是 【1】

    string和slice:

    1)string底层是一个byte数组,因此string也可以进行切片处理

    案例演示:

    func main() {

      str := "hello@atguigu"
      slice := str[6:]
      fmt.Println("slice=",slice)
    }

    2)string和切片在内存的形态,以“abcd” 画出内存示意图

    3)string是不可变的,也就说不能通过 str[0] = 'z' 方式来修改字符串

    4)如果需要修改字符串,可以先将string -> []byte / 或者 []rune -> 修改 -> 重写转成string

    func main() {

      str := "hello@atguigu"
      slice := str[6:]
      fmt.Println("slice=",slice)

      //str[0] = 'z' [编译不会通过,报错,原因是string是不可变的]

      // arr1 := []byte(str)
      // arr1[0] = 'z'
      // str = string(arr1)
      // fmt.Println("str=", str)

      //细节,我们转成[]byte后,可以处理英文和数字,但是不能处理中文
      //原因是 []byte 按字节来处理的,而一个汉字是3个字节,因此就会出现乱码
      //解决方法是将 string 转成 []rune 即可,因为 []rune是按字符处理,兼容汉字
      arr1 := []rune(str)
      arr1[0] = '北'
      str = string(arr1)
      fmt.Println("str=", str)
    }

  • 相关阅读:
    C
    A
    G
    B
    一些新玩意:
    Angular常用功能
    node学习笔记(四)
    node学习笔记(三)
    node学习笔记(二)
    node学习笔记
  • 原文地址:https://www.cnblogs.com/green-frog-2019/p/11355508.html
Copyright © 2011-2022 走看看