切片的定义,切换和数组的区别,切片的截取,切片和底层数组的关系,append函数,copy函数,切片做函数参数
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
//1、切片的定义
//[low:high:max] //slice本质上不是数组,是一种数据结构
//low,下标的起点
//high,下标的终点(不包括此下标),[a[low],a[high]),左闭右开
//len = high - low//长度
//cap = max = low//容量
a := []int{1, 2, 3, 4, 5} //[...]里面的...可以省略
s := a[0:3:5]
fmt.Println("s = ", s)
fmt.Println("len(s) = ", len(s)) //长度3-0
fmt.Println("cap(s) = ", cap(s)) //容量5-0
s = a[1:4:5]
fmt.Println("s = ", s)
fmt.Println("len(s) = ", len(s)) //长度4-1
fmt.Println("cap(s) = ", cap(s)) //容量5-1
//2、切片和数组的区别
//数组[]里面是一个固定的常量,不能修改大小,len和cap永远都是常量
var b [5]int
fmt.Printf("len(b) = %d, cap(b) = %d\n", len(b), cap(b))
//切片[]里面为空,或者为...,切换的长度和容量可以不固定
var c []int
fmt.Printf("len(c) = %d, cap(c) = %d\n", len(c), cap(c)) //0,0
c = append(c, 11) //给切片末尾追加一个成员
fmt.Printf("len(c) = %d, cap(c) = %d\n", len(c), cap(c)) //0,0
//3、切片的创建
//自动推导类型,同时初始化
s1 := []int{1, 2, 3, 4}
fmt.Println("s1 = ", s1)
//使用make函数,格式 make(切片类型,长度len,容量cap)
s2 := make([]int, 5, 10)
fmt.Printf("len(s2) = %d,cap(s2) = %d\n", len(s2), cap(s2))
//没有指定容量,容量和长度一样
s3 := make([]int, 5)
fmt.Printf("len(s3) = %d,cap(s3) = %d\n", len(s3), cap(s3))
//4、切片的截取
array := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s4 := array[:] //[0:len(array):cap(array)]
fmt.Println("s4 = ", s4)
fmt.Printf("len(s4) = %d, cap(s4) = %d\n", len(s4), cap(s4)) //10,10
//操作某个元素,和数组操作方式一样
d := array[0]
fmt.Println("d = ", d)
e := s4[5]
fmt.Println("e = ", e)
s5 := array[3:6:7] //a[3],a[4],a[5],len=6-3,cap=7-3
fmt.Println("s5 = ", s5)
fmt.Printf("len(s5) = %d, cap(s5) = %d\n", len(s5), cap(s5)) //3,4
s6 := array[:6] //下标从0开始,取6个元素
fmt.Println("s6 = ", s6)
fmt.Printf("len(s6) = %d, cap(s6) = %d\n", len(s6), cap(s6)) //6,10
s7 := array[3:] //从下标3开始,到结尾
fmt.Println("s7 = ", s7)
fmt.Printf("len(s7) = %d, cap(s7) = %d\n", len(s7), cap(s7)) //7,7
//5、切片和底层数组的关系
f := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
//切片1
e1 := f[2:5] //从下标2开始,取3个元素
e1[1] = 666 //通过切片改变底层数组的值
fmt.Println("e1 = ", e1)
fmt.Println("f = ", f)
//切片2
e2 := e1[2:7] //从下标e1[2]开始,可以看成是底层数组指针的起点,取5个元素,只要底层数组不越界即可
e2[2] = 777
fmt.Println("e2 = ", e2)
fmt.Println("f = ", f)
//6、append函数
s8 := []int{}
s8 = append(s8, 1) //在原切片的末尾添加新元素,返回新切片
s8 = append(s8, 2)
s8 = append(s8, 3)
fmt.Println("s8 = ", s8)
//append扩容方式:如果超过原来的容量,通常以2倍容量扩容
s9 := make([]int, 0, 1) //容量为1
oldCap := cap(s9)
for i := 0; i < 8; i++ {
s9 = append(s9, i)
if newCap := cap(s9); newCap > oldCap {
fmt.Printf("cap:%d========>%d\n", oldCap, newCap)
oldCap = newCap
}
}
//7、copy函数
srcSlice := []int{1, 2} //上拷贝到下,下变为1,2,6,6;下拷贝到上,上变为6,6
detSlice := []int{6, 6, 6, 6}
copy(detSlice, srcSlice) //把对应下标拷贝过去
fmt.Println("detSlice = ", detSlice) //1,2,6,6
//8、切片做函数参数
//以引用方式传递参数
n := 10
s10 := make([]int, n)
rand.Seed(time.Now().UnixNano())
InitData(s10)
fmt.Println("排序前:s10 = ", s10)
BubbleSort(s10)
fmt.Println("排序后:s10 = ", s10)
}
//初始化切片
func InitData(a []int) {
for i := 0; i < len(a); i++ {
a[i] = rand.Intn(100)
}
}
//切片排序
func BubbleSort(a []int) {
for i := 0; i < len(a)-1; i++ {
for j := 0; j < len(a)-1-i; j++ {
if a[j] > a[j+1] {
a[j], a[j+1] = a[j+1], a[j]
}
}
}
}
s = [1 2 3]
len(s) = 3
cap(s) = 5
s = [2 3 4]
len(s) = 3
cap(s) = 4
len(b) = 5, cap(b) = 5
len(c) = 0, cap(c) = 0
len(c) = 1, cap(c) = 1
s1 = [1 2 3 4]
len(s2) = 5,cap(s2) = 10
len(s3) = 5,cap(s3) = 5
s4 = [0 1 2 3 4 5 6 7 8 9]
len(s4) = 10, cap(s4) = 10
d = 0
e = 5
s5 = [3 4 5]
len(s5) = 3, cap(s5) = 4
s6 = [0 1 2 3 4 5]
len(s6) = 6, cap(s6) = 10
s7 = [3 4 5 6 7 8 9]
len(s7) = 7, cap(s7) = 7
e1 = [2 666 4]
f = [0 1 2 666 4 5 6 7 8 9]
e2 = [4 5 777 7 8]
f = [0 1 2 666 4 5 777 7 8 9]
s8 = [1 2 3]
cap:1========>2
cap:2========>4
cap:4========>8
detSlice = [1 2 6 6]
排序前:s10 = [54 37 22 4 30 68 38 29 33 73]
排序后:s10 = [4 22 29 30 33 37 38 54 68 73]