切片的概念比较复杂,一定要注意他的四要素:
/1. 切片有长度,2. 切片有容量,3. 切片共享底层数据, 4. 用append改变长度和容量
package main
import ("fmt")
func main() {
//切片:
//切片和数组最大的区别就是切片定义的时候[]是空,而数组使用[Num]或者[...]定义长度
arr1 := [...]int{1,2,3,4} //我是数组
arr2 := [4]int{1,2,3,4} //我是数组too
fmt.Println(len(arr1))
fmt.Println(cap(arr2))
sli1 := []int{1,2,3,4} //我是切片
fmt.Println(len(sli1))
fmt.Println(cap(sli1))
//切片的四大特性:
//1. 切片有长度,2. 切片有容量,3. 切片共享底层数据, 4. 用append改变长度和容量
//初始化切片
sli2 := []string{"blue","green","red","black"} //len=4, cap= 4
sli3 := make([]int,3,5) //len=3,cap =5
fmt.Println(cap(sli2))
fmt.Println(sli3) //[0 0 0]
fmt.Println(cap(sli3)) //5
//切片可以通过索引找到value
fmt.Println(sli2[3]) //black
//创建100个为空的slide
sli4 :=[]string{99:""}
fmt.Println(sli4)
//创建1个nil切片
sli5 :=[]int{}
fmt.Println(sli5) //len=0,cap=0
//共享底层数据
//无论几层切片,在slide:=oldslide[a:b]时,b一定不能大于cap(oldslide),否则会报错
//无论几层切片,在slide:=oldslide[a:b:c]时,slide的len = b-a, cap = c-a;
//append时:如果slide:=oldslide[a:b],共享底层数据。slide := append(slide,d)。
//--当b<cap(oldslide)的时候,由于共享底层数据,则底层数据被直接修改为d
//--当b>cap(oldslide)时,由于共享底层数据,则slide的cap会成倍增加。并将d悬挂在后面
//append时:如果slide:=oldslide[a:b:b],会将底层数据按照切片copy相应的len和cap,并划分内存地址。slide := append (slide, d)
//并不会改变底层数据,而是改变slide。
sli6 := []*int{0:new(int),1:new(int),2:new(int),3:new(int),4:new(int)}
*sli6[0]=0
*sli6[1]=1
*sli6[2]=2
*sli6[3]=3
*sli6[4]=4
fmt.Println(sli6)
for i:=0;i<len(sli6);i++ {
fmt.Println(*sli6[i])
}
sli7 := sli6[2:3]
fmt.Println(cap(sli7)) //3
slid1 := []int{1,2,3,4,5,6}
slid2 := slid1[2:4] //将slid1的第2,3位切出来[2,3],并在slid2的索引重新标记成0,1
slid2[1] =88 //slid2的第1位重写位88
fmt.Println(slid1,slid2) //[1 2 3 88 5 6] [3 88] //slid1和slid2都会重写
slid3 := append(slid2,77)
fmt.Println(slid1,slid2,slid3) //[1 2 3 88 77 6] [3 88] [3 88 77] //append会将底层数据修改
//使用append增加len和cap
slid4 := append(slid1,55)
fmt.Println(cap(slid4),slid4) //12 [1 2 3 88 77 6 55] //cap成倍增加
//切片的第三个参数 slide[a:b:c]
slid5 := []string{"Apple", "Orange", "Plum", "Banana", "Grape"}
slid6 := slid5[2:3:4] //len:3-2=1, cap: 4-2=2//表示从第2位开始计算,len=1,cap=2
fmt.Println(len(slid6),cap(slid6),slid6)
slid7 := slid5[2:3:3]//len:3-2=1, cap: 3-2=1/当我们第一次对 slice 调用 append 的时候,会创建一个新的底层数组,这个数组包
//括 2 个元素,并将水果 Plum 复制进来,再追加新水果 Kiwi,并返回一个引用了这个底层数组 的新切片
slid7 = append(slid7,"kiwi")
fmt.Println(slid5,slid7) //[Apple Orange Plum Banana Grape] [Plum kiwi]
这个地方插播个广告。在《GO语言实践》中时这么描述的:
image.png
继续:
//迭代:
for index,value :=range slid5 {
fmt.Printf("Index: %d Value: %s\n", index, value)
}
//Index: 0 Value: Apple
//Index: 1 Value: Orange
//Index: 2 Value: Plum
//Index: 3 Value: Banana
//Index: 4 Value: Grape
//不想打印index的话,可以使用_代替
for _,value :=range slid5 {
fmt.Printf("Value: %s\n", value)
}
//Index: 0 Value: Apple
//Index: 1 Value: Orange
//Index: 2 Value: Plum
//Index: 3 Value: Banana
//Index: 4 Value: Grape
//使用循环对切片进行迭代:
for index :=2;index <len(slid5);index++ {
fmt.Printf("Index: %d Value : %s\n",index,slid5[index])
}
//Index: 2 Value : Plum
//Index: 3 Value : Banana
//Index: 4 Value : Grap
//切片套娃:
slid8 :=[]int{1,2}
slid9 :=[]int{3,4}
fmt.Printf("%v\n",append(slid8,slid9...)) //[1 2 3 4]
//一定要加... 不然会报错:cannot use slid9 (type []int) as type int in append
运行结果:
4
4
4
4
4
[0 0 0]
5
black
[ ]
[]
[0xc00000a0f0 0xc00000a0f8 0xc00000a100 0xc00000a108 0xc00000a110]
0
1
2
3
4
3
[1 2 3 88 5 6] [3 88]
[1 2 3 88 77 6] [3 88] [3 88 77]
12 [1 2 3 88 77 6 55]
1 2 [Plum]
[Apple Orange Plum Banana Grape] [Plum kiwi]
Index: 0 Value: Apple
Index: 1 Value: Orange
Index: 2 Value: Plum
Index: 3 Value: Banana
Index: 4 Value: Grape
Value: Apple
Value: Orange
Value: Plum
Value: Banana
Value: Grape
Index: 2 Value : Plum
Index: 3 Value : Banana
Index: 4 Value : Grape
[1 2 3 4]
Process finished with exit code 0