2.1 数组 切片 - hairyOwl/golangLearn GitHub Wiki

一 数组

数组是值类型 值传递 参数拷贝

- [3]int 和 [5]int是不同的类型
- 调用func f( arr [5]int) 会 **拷贝**数组
- go语言一般不直接使用数组而是切片

1.1 数组的定义

var arr1 [5]int // [0,0,0,0,0]  
arr2 := [3]int{1, 2, 3}  
arr3 := [...]int{2, 3, 4}  
//二维数组  
var grid [4][5]float64

1.2 数组遍历

  • for i := 0; i < len(arr3); i++
  • for i, v := range arr3 推荐 range
  1. 意义明确
  2. c++ 本身没有 通过第三方库可以实现
  3. java/Python只能for each value不能同时获取i v

二 切片 Slice

2.1 切片的概念

2.1.1 切片的声明

Slice本身没有数据,是对底层array的一个view(视图)

arr := [...] int{0,1,2,3,4,5,6,7}
s := arr[2:6]     // [2 3 4 5]  前闭后开

2.1.2 再次切片 Reslice

fmt.Println(s2) //[100 1 100 3 4 5 6 7]  
s2 = s2[:5]  
fmt.Println(s2) //[100 1 100 3 4]  
s2 = s2[2:]  
fmt.Println(s2) //[100 3 4]

2.1.3 Slice的扩展

  • slice可以向后扩展,不可以向前扩展
  • s[i]不可以超越len(s) ,向后扩展不可以超越底层数组cap(s)
arr[0], arr[2] = 0, 2  
s1 = arr[2:6]  
s2 = s1[3:5] //[s1[3],s1[4]]  
//fmt.Println(s1[4]) //ERROR : index out of range  
fmt.Println(s1) //[2 3 4 5]  
fmt.Println(s2) //[5] x [5 6] √

image

  • ptr: 切片开始的位置
  • len: 切分的长度 ,[]可以取到的有效下标
  • cap: ptr到arry的结尾,不超过cap都能扩展

image

2.2 切片的操作

2.2.1 向Slice添加元素

  • 添加元素时如果超越cap,系统会重新分配更大的底层数组
  • 重新分配更大的底层数组是原始数组拷贝而成,如果原始数组后续未引用会被垃圾回收
  • 由于值转递的关系,必须接受append的返回值
    1. append后为未超出原始cap,就会改变len。
    2. append后为超出原始cap,就会改变ptr len cap。

2.2.2 slice的创建

  • 声明后赋值
  • 知道声明切片的len,但不打算创建的时候赋值
  • 知道声明切片的len cap,但不打算创建的时候赋值
s1 := []int{2, 4, 6, 8} //是{2,4,6,8}数组的view  
s2 := make([]int, 16) //知道声明切片的len,但不打算创建的时候赋值  
s3 := make([]int, 16, 32) //知道声明切片的len cap,但不打算创建的时候赋值

2.2.3 slice的复制、删除

slice的复制

copy(s2, s1) //dst目标 src被复制

slice的删除

fmt.Println("切片中的元素删除")  
s2 = append(s2[:3], s2[4:]...) //删除s2[3]  
printSlice(s2) //[2 4 6 0 0 0 0 0 0 0 0 0 0 0 0]  
  
fmt.Println("获取切片的头")  
front := s2[0]  
s2 = s2[1:]  
fmt.Println(front) //2  
printSlice(s2) //[4 6 0 0 0 0 0 0 0 0 0 0 0 0] len= 14 cap= 15  
  
fmt.Println("获取切片的尾")  
tail := s2[len(s2)-1]  
s2 = s2[:len(s2)-1]  
fmt.Println(tail) //0  
printSlice(s2) //[4 6 0 0 0 0 0 0 0 0 0 0 0] len= 13 cap= 15

BUG 🐞

链接🔗