数组

快速入门

  1. //定义数组
  2. var hens [6]float64
  3. //遍历、赋值、输出
  4. for i := 0; i < len(hens) ; i++ {
  5. hens[i] = float64(i)
  6. }

内存布局

image.png

初始化

  1. //初始化 - 四种方式
  2. var array1 [3]int = [3]int{1,2,3}
  3. var array2 = [3]int{1,2,3}
  4. var array3 = [...]int{1,2,3}
  5. var array4 = [...]int{0:100,1:500,4:999,3:1000}
  6. fmt.Println(array1) [1 2 3]
  7. fmt.Println(array2) [1 2 3]
  8. fmt.Println(array3) [1 2 3]
  9. fmt.Println(array4) [100 500 0 1000 999]

数组遍历

  1. //数组遍历
  2. // 常规方式
  3. for i := 0; i < len(array1); i++ {
  4. fmt.Println(array1[i])
  5. }
  6. // for-range ---- key,value名字自己指定
  7. for key, value := range array1 {
  8. fmt.Println(key,value)
  9. }
  10. for _, value := range array1 {
  11. fmt.Println(value)
  12. }

注意事项

  1. 数组是多个相同的数据类型的组合,一旦一个数组声明后,其长度是固定的,不能动态变化。
  2. var arr []int 是一个切片,slice 区别于数组
  3. 数组创建后,如果没有赋值,有默认值
  4. 数组默认是值传递,因此进行值拷贝,不会影响作为参数传入的原数组
  5. 如果想修改原数组,可以使用引用传递(指针)
  6. 长度是数组的一部分,在传递参数时,必须考虑数组的长度

image.png

切片

  1. 切片英文slice
  2. 切片是数组的一个引用
  3. 切片的长度是可以变化的
  4. 切片的使用方式和数组类似,遍历、访问
  5. 切片定义的基本语法 : var a []int

    1. //快速入门
    2. array := [5]int{1,2,3,4,5}
    3. //切片slice引用数组array下标 [1,3)个元素
    4. slice := array[1:3]
    5. fmt.Println(slice) //[2,3]
    6. fmt.Println(len(slice)) //2
    7. fmt.Println(cap(slice)) //4

切片使用方式

  1. //使用方式1 : 定义切片去引用创建好的数组 slice := array[1:3]
  2. arr := [5]int{1,2,3,4,5}
  3. //切片slice引用数组array下标 [1,3)个元素
  4. slice1 := arr[1:3]
  5. fmt.Println(slice1)
  6. //使用方式2 : 通过make创建切片
  7. var slice2 = make([]int,4,10) //切片类型、len、cap
  8. fmt.Println(slice2)
  9. //使用方式3 : 直接指定具体数组
  10. var slice3 = []int{1,3,5}
  11. fmt.Println(slice3)

内存布局

image.png

  1. slice是一个引用类型
  2. slice可以理解为一种数据结构,

type slice struct{
*ptr
len
cap
}

append

  1. //append
  2. var slice4 = []int{100,200,300}
  3. slice5 := append(slice4,400,500,600) //追加元素
  4. slice6 := append(slice4,slice4...) //追加切片
  5. fmt.Println(slice4,len(slice4),cap(slice4),&slice4[0])
  6. fmt.Println(slice5,len(slice5),cap(slice5),&slice5[0])
  7. fmt.Println(slice6,len(slice6),cap(slice6),&slice6[0])
  8. [100 200 300] 3 3 0xc042010340
  9. [100 200 300 400 500 600] 6 6 0xc04200a390
  10. [100 200 300 100 200 300] 6 6 0xc04200a3c0
  1. 切片底层append操作的本质是对数组扩容
  2. go底层会创建一个新的数组newArr(扩容后大小)
  3. 将slice原来包含的内容拷贝到新的数组newArr
  4. 返回新slice的引用

    copy

    1. //copy
    2. var slice7 = []int{101,202,303}
    3. var slice8 = make([]int,10,10)
    4. fmt.Println(slice7,slice8)
    5. [101 202 303] [0 0 0 0 0 0 0 0 0 0]
    6. copy(slice8,slice7)
    7. fmt.Println(slice7,slice8)
    8. [101 202 303] [101 202 303 0 0 0 0 0 0 0]
    9. fmt.Println(&slice7[0],&slice8[0])
    10. 0xc042056120 0xc04208a050
  5. copy(a,b)要求两个参数都是切片

  6. a、b的数据空间是独立的,互不影响

slice和string

  1. //string 和 slice
  2. str := "helle"
  3. fmt.Println(str) //helle
  4. sliceA := []byte(str)
  5. sliceA[4] = 'o'
  6. str = string(sliceA[0])
  7. fmt.Println(str) //hello
  8. str_2 := "我love你"
  9. fmt.Println(str_2) //我love你
  10. sliceB := []rune(str_2)
  11. sliceB[0] = 'I'
  12. str_2 = string(sliceB)
  13. fmt.Println(str_2) //Ilove你
  1. string底层是一个byte数组,因此string也可以进行切片处理
  2. string是不可修改的,不可以通过 str[0]=’z’ 的方式修改字符串
  3. 如果需要修改字符串,先将string转化为 []byte 或者 []rune =》 修改 =》 重新转换为string
  4. 转化为 []byte 可以处理英文和数字,但不能处理中文(一个汉字三个字节)
  5. 转化为 []rune 可以处理英文和数字、以及中文

    注意事项

image.png