和数组的区别

1.数组是定长,切片不是
2.数组是值传递,切片不是

声明

1.通过var声明
2.简短声明

package main

import "fmt"

func main() {
   var a []int
   var b = []int{1,2,3}
   var c = []int{1,2,3}
   d := []int{1,2,3}
   e := []string{"a"}
   fmt.Println(a,b,c,d,e)
}

3.使用make创建

package main

import "fmt"

func main() {
	//使用make创建的好处是可以方便的指定切片长度和容量
	a := make([]int,5,6)
	fmt.Println(len(a),cap(a))
}

空切片可以和nil相等

package main

import "fmt"

func main() {
   var s []int
   //空切片可以和nil相等
   //result:true
   fmt.Println(s == nil)
}

切片长度,容量

1.长度使用len获取,容量使用cap获取

package main

import "fmt"

func main() {
	a := make([]int,5,6)
	fmt.Println(len(a),cap(a))
}

2.长度是当前可见元素个数 ,容量的作用: 在容量范围内是引用,超过容量后才会进行扩容分配

package main

import "fmt"

func main() {
	//one start
	//指定长度4,容量7
	a := make([]int, 4, 7)
	fmt.Println(len(a), cap(a))
	//one end

	//two start
	//长度是当前可见元素个数 ,容量的作用: 在容量范围内是引用,超过容量后才会进行扩容分配
	b := a[2:3]

	//result:[0 0]
	fmt.Println(b)
	b[0] = 22
	//result:[0 0 22 0] [22]
	//因为是引用,所以a中元素也会跟着改变
	fmt.Println(a, b)
	//two end

	//three
	c := append(a[:],1,2,3)
	c[0] = 666
	//result: [666 0 22 0]
	fmt.Println(a)
	d := append(a[:],1,2,3,4)
	d[0] = 888
	//result: [666 0 22 0] 超过容量,重新分配,所以a不会受影响
	fmt.Println(a)
}

在这里插入图片描述

3.容量计算方式: next_cap = cap - start
cap可以缩小(但是必须大于等于end)
扩容后的新切片会重新分配容量

package main

import "fmt"

func main() {
   a := make([]int,3,7)

   //result:7
   fmt.Println(cap(a))

   b := a[2:]
   //result: 7 - 2 = 5
   fmt.Println(cap(b))

   c := b[1:2]
   //result: 5 - 1 = 4
   fmt.Println(cap(c))
}

package main

import "fmt"

func main() {
	a := make([]int, 3, 7)
	
	//指定容量=4
	b := a[0:3:4]
	//result: 不是 7-0 而是 4-0
	fmt.Println(cap(b))
	//指定容量=2
	c := b[1:2:2]
	//result:2-1=1
	fmt.Println(cap(c))
}

切片增加元素

使用append尾部追加

package main

import "fmt"

func main() {
	a := []int{1,2,3,4,5}
	b := append(a,6,7)
	fmt.Println(b) //[1 2 3 4 5 6 7]
}

切片删除元素

1.从头删除
2.从尾部删
3.使用append实现从中间删

package main

import "fmt"

func main() {
  //从头部删
  a := []int{1,2,3,4}
  fmt.Println(a[1:])

  //从尾部删
  fmt.Println(a[0:len(a) - 1])

  //从中间删(删除2) append + slice
  fmt.Println(append(a[0:1],a[2:]...))
}

4.使用copy实现从中间删除

package main

import "fmt"

func main() {
	//从头部删
	a := []int{1, 2, 3, 4}
	fmt.Println(a[1:])

	//使用copy实现从中间删除(删除2)
	//copy(p1,p2) p2中的参数覆盖p1中的参数(set p1[0] = p2[0],p1[1]=p2[1],p1[n]=p2[n]......)
	b := a[1:] //[2,3,4]
	c := a[2:] //[3,4]
	//b 变成 3 4 4 a 变成 1 3 4 4
	copy(b,c)
	// 1,3,4
	fmt.Println(a[0:len(a) - 1])
}

切片排序

提供了切片排序函数,常用的有(sort.Ints,sort,Strings)

package main

import (
	"fmt"
	"sort"
)


func main() {
  a := []int{1,5,2,4}
  c := []string{"a","e","b","c"}
  sort.Ints(a)
  sort.Strings(c)
  fmt.Println(a)
  fmt.Println(c)
}

切片截取范围

切片截取范围可以大于len小于等于cap

package main

import "fmt"

func main() {
   a := make([]int,3,6)

   //切片截取范围可以大于len小于等于cap
   b := a[:]
   //大于0小于等于6即可
   c := a[:6]
   fmt.Println(b) //[0 0 0]
   fmt.Println(c) //[0 0 0 0 0 0]
}

多维切片

package main

import "fmt"

func main() {
   //多维切片
	a := make([][]int,2,3)
	fmt.Println(a) //[[][]]
	a[0] = []int{1,2,3}
	fmt.Println(a) //[[1 2 3] []]
}