和数组的区别
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] []]
}