代码加注释撸起来

package main/***  @Description:数组与切片*  @Author: guai*  @Date:2020/2/21 9:15
**/
import ("fmt""math/rand""time"
)func main() {//1、数组//在go语言中数组属于值类型 在默认情况下是值传递,因此作为形参时会进行值拷贝//且在作为形参时,必须指明数组的长度,只有当形参数的长度与要传递的参数的长度一致才可以成功传值//1.1、数组的定义及使用var hens [7]float64hens[0] = 3.0hens[1] = 5.0hens[2] = 4.0hens[3] = 5.0hens[4] = 6.0hens[5] = 7.0hens[6] = 8.0totalWeight := 0.0for i := 0; i < len(hens); i++ {totalWeight += hens[i]}fmt.Println("鸡的总重:", totalWeight)//1.2、数组定义和内存布局//定义 var 数组名 [数组大小]数据类型//1.3、数组在内存中的布局://1)数组的地址可以通过数组名来获取 即&hens//2)数组的一个元素的地址,就是数组的首地址//3)数组的各个元素的地址间隔时依据数组的类型决定,int64->8 int32->4...fmt.Printf("hens的地址=%p hens[0]的地址%p hens[1]的地址%p\n", &hens, &hens[0], &hens[1])//1.3、数组初始化的方式var numArr [3]int = [3]int{1, 2, 3}fmt.Println("numArr:", numArr)var numArr1 = [3]int{1, 2, 3}fmt.Println(numArr1)var numArr2 = [...]int{1, 2, 3}fmt.Println(numArr2)//通过下标为指定数组的指定位置赋值var numArr4 = [...]int{1: 8080, 0: 4545, 2: 111}fmt.Println(numArr4)//1.4、数组的遍历//for--range  for index, val:=range arry{// 说明: 第一个返回值index是数组的下标 ,若不想使用 可用 _占位忽略符代替var strArr = [3]string{"hello ", "world! ", "__乖 "}for _, val := range strArr {fmt.Println("for--range 输出字符串:", val)}//1.5、数组的应用//通过循获取一个A-Z的字符数组并输出var varChars [26]bytefor i := 0; i < len(varChars); i++ {//将i转为byte类型varChars[i] = 'A' + byte(i)}for i := 0; i < len(varChars); i++ {fmt.Printf("%c", varChars[i])}fmt.Println()//随机生成五个数并反转打印var intVarArr [5]intlen := len(intVarArr)//为使尝产生的随机数不相同需要设置随机种子rand.Seed(time.Now().UnixNano())for i := 0; i < len; i++ {intVarArr[i] = rand.Intn(100)}fmt.Println("交换前:", intVarArr)for i := 0; i < len/2; i++ {temp := intVarArr[i]intVarArr[i] = intVarArr[len-i-1]intVarArr[len-i-1] = temp}fmt.Println("交换后:", intVarArr)//2、切片//2.1、当用数组保存一组个数不确定的数据时,可使用切片//1)切片slice 是数组的引用,因此切片是引用类型,//2)切片的长度可以变化,是一个动态变化数组//切片定义的基本语法:  var 切片名 []类型//sliece从底层来说是一个结构体(struct)// type slice struct{// 	ptr *[2]int// 	len int// 	cap int// }//2.1、切片的使用一var intVarArr1 [5]int = [...]int{1, 2, 3, 4, 5}//定义切片,引用i那天VarArr1数组从0开始到4slice := intVarArr1[0:5]fmt.Println("切片的内容:", slice)fmt.Println("切片的容量;", cap(slice))//2.2、切片的使用二//var 切片名 []type =make([]type ,len,[cap])  cap可选//此方法创建的切片对应的数组有make底层维护,对外不可见,即只能通过slice访问各个元素var floatSlice []float64 = make([]float64, 10)floatSlice[1] = 10floatSlice[9] = 10fmt.Println("使用make创建slice:", floatSlice, " cap: ", cap(floatSlice))//2.3、切片的使用三//定义切片直接指定具体数组,使用原理类似make方式var strSlice []string = []string{"hello", "world", "_乖"}fmt.Println("strSlice=", strSlice)fmt.Println("strSlice cap=", cap(strSlice))//2.4、切片可以继续切片var intVarArr2 = [...]int{1, 2, 3}slice1 := intVarArr2[0:3]slice2 := slice1[0:3]fmt.Println("切片的切片:", slice2)//2.5、使用append内置函数,对切片动态追加//底层原理分析//切片append操作本质是对数组扩容//go底层会创建一个新的数组newArr(大小为扩容后数组的大小)//将slice原来包含的元素拷贝到新的数组newArr//最后slice重新引用新的数组var slice3 []int = []int{1, 2, 3}fmt.Println("slice的动态追加:", slice3, " cap:", cap(slice3))slice3 = append(slice3, 1, 2, 3)fmt.Println("slice的动态追加:", slice3, " cap:", cap(slice3))//2.6、切片的拷贝操作//切片使用copy内置函数完成copy//当目标slic的长度小于源slice的长度时,只copy目标长度的内容//如 下:var slice4 []int = []int{1, 2, 3}//只copyslice中的前两个元素var slice5 = make([]int, 2)copy(slice5, slice4)slice5[0] = 0fmt.Println("切片的copy:slice4:", slice4, " slice5", slice5)//若直接使用赋值符号:slice5 = slice4slice5[0] = 0fmt.Println("切片的直接复制:slice4:", slice4, " slice5", slice5)//通过对比结果会发现,使用赋值符号是,时将slice5指向slice4指向的内存,当修改slice5时修改的时它们公用的内存//而copy则是为slice5开辟了新的内存空间然后将slice4的值copy到新的内存空间中//3、string和slice//string底层是一个byte数组,因此string也可以进行切片处理//[:]表示下标从0开始到最后//[a:] 表示从a开始到最后//[:a]从0开始到astr := "hello world!"slice6 := str[:]fmt.Println("slice6:", slice6)
}