第五章、go语言复合类型,11_复合类型_切片

切片的定义,切换和数组的区别,切片的截取,切片和底层数组的关系,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]

你可能感兴趣的:(GO语言,go,golang)