slice - 图1

复制

  1. a := []int{1,2,3,4,5}
  2. b := make([]int, len(a))
  3. copy(b, a)

注意:copy(b, a)将a中的值复制到b,复制多少位取决于b的长度,若b的长度位2,则a只会复制前两位给b

删除

  1. func Remove(s []int, index int) ([]int, error) {
  2. lens := len(s)
  3. if index < 0 || index >= lens {
  4. return nil, errors.New("Bad Index!")
  5. }
  6. // 若s的元素是指针类型或包含指针字段的结构体类型,删除指定元素之后,元素并不会被GC回收,需添加下列代码进行清理
  7. // s[index] = nil
  8. if index == lens -1 {
  9. return s[:lens-1], nil
  10. }else {
  11. return append(s[:index], s[index+1:]...), nil
  12. }
  13. }

插入

  1. func Insert(s []int, elem, index int) ([]int, error) {
  2. if index < 0 || index > len(s) {
  3. return nil, errors.New("Bad Index!")
  4. }
  5. s = append(s, 0)
  6. copy(s[index+1:], s[index:])
  7. s[index] = elem
  8. return s, nil
  9. }
  1. func main() {
  2. var s = [10]int{1,2,3,4,5,6,7,8,9}
  3. // len=3 cap = 9
  4. s1 := s[1:4]
  5. fmt.Println(s1) // s1 = [2 3 4]
  6. // 编译错误: 越界
  7. s2 := s[:11]
  8. // 编译错误:索引必须非负
  9. s3 := s1[-1:]
  10. // s1中只有三个元素,此处复制5个元素
  11. s4 := s1[:5]
  12. fmt.Println(s4) // 不会报错,s4 = [2 3 4 5 6]
  13. // s1的cap是9,此处复制10个元素
  14. s5 := s1[:10]
  15. fmt.Println(s5) // panic range [:10] with capacity 9
  16. }

image.png
image.png
image.png

append可能存在的陷阱

使用append之后,底层数组可能是同一个,也可能不是,这就会导致对原有数组的修改会影响新数组,也可能不会有影响,从而导致代码的不确定性

  1. a := []int{1, 2, 3}
  2. fmt.Println("a的cap:", cap(a)) //3
  3. b := append(a, 4)
  4. fmt.Println("a的cap:", cap(b)) //6
  5. b[2] = 99
  6. c := append(b, 5)
  7. fmt.Println("a的cap:", cap(c)) //6
  8. c[3] = 88
  9. fmt.Println(a) // [1 2 3]
  10. fmt.Println(b) // [1 2 99 88]
  11. fmt.Println(c) // [1 2 99 88 5]