Golang 错误处理丶数组丶切片丶随机数
一.错误处理
1 // 错误处理 2 func testError() { 3 errorExec := func() { 4 err := recover() // recover是内置函数,可以捕获异常 5 if err != nil { // 说明捕获到错误 6 fmt.Println("err=", err) 7 } 8 } 9 errorFunc := func() { 10 defer errorExec() // 捕获错误进行处理 11 num1 := 10 12 num2 := 0 13 res := num1 / num2 // 程序崩溃,不做错误处理,代码不会继续执行 14 fmt.Println("error", res) 15 } 16 17 errorFunc() // 如果函数内部没有作错误处理,程序就会崩溃.下面的print就不会打印了 18 fmt.Println("错误处理!") 19 20 // 另一种错误处理方式 21 err := func(fileName string) (err error) { 22 err = nil 23 24 if fileName != "Config.ini" { 25 return errors.New("读取配置文件错误!\n") 26 } 27 28 return 29 }("Config.ini1") 30 31 if err != nil { 32 // panic()是内置函数如果读取文件发生错误,就输出这个错误,并终止程序 33 panic(err) 34 } 35 36 }
二.数组使用细节
1 func testArray(n1 int32, args ...int) { 2 3 // 数组参数 4 if len(args) > 0 { 5 fmt.Printf("不固定参数:%v , 参数类型: %T \n", args, args) 6 } 7 8 // 数组初始化 9 var numArr01 [3]int = [3]int{1, 2, 3} 10 fmt.Println("第一种初始化数组的方法:", numArr01) 11 12 var numArr02 = [3]int{10, 20, 30} 13 fmt.Println("第二种初始化数组的方法:", numArr02) 14 15 var numArr03 = [...]int{11, 21, 31} 16 fmt.Println("第三种初始化数组的方法:", numArr03) 17 18 var numArr04 = [3]int{0: 110, 2: 210, 1: 310} 19 fmt.Println("第四种初始化数组的方法:", numArr04) 20 21 // 数组遍历 22 for index, value := range numArr04 { 23 fmt.Println("数组索引(可用下划线_忽略它):", index, " , 索引对应值:", value) 24 } 25 26 for i := 0; i < len(numArr01); i++ { 27 fmt.Printf("%v", &numArr01[i]) 28 } 29 fmt.Println("==========range是赋值,改变val并不能修改数组======") 30 for _, val := range numArr01 { 31 fmt.Printf("%v", &val) 32 } 33 34 // 数组注意事项和细节: 35 // 1.元素类型相同,长度固定 36 // 2.var arr = []int 这里不写长度是切片 37 // 3.数组未设定初始值,默认0 38 // 4.下标越界报panic 39 // 5.数组是值类型 40 // 6.在Golang中长度是类型的一部分. 41 // var p1 *[3]int = &numArr04 // 类型一致不报错 42 // var p2 *int = &numArr04[0] // 类型一致不报错 43 // var p3 *[4]int = &numArr04 // numArr04的长度是3,与p3长度不匹配,编译报错 44 // var p4 *[2]int = &numArr04 // 同上 45 // var p5 *[]int = &numArr04 // 不指定更是错误 46 // fmt.Println(p1, p2, p3, p4, p5) 47 }
三.随机数
1 func testRand() { 2 // rand.Seed(time.Now().UnixNano()) 现在不用初始化随机种子了 3 fmt.Println(rand.Intn(64)) // 获得一个0 到 64 之间的随机数 4 fmt.Println(rand.Intn(64)) 5 fmt.Println(rand.Intn(64)) 6 fmt.Println(rand.Intn(64)) 7 fmt.Println(rand.Intn(64)) 8 }
四.切片使用细节
1 func testSlice() { 2 // 字符串转切片 3 str1 := "hello 中国" 4 slice := []rune(str1) 5 slice[0] = int32(97) 6 // slice := str1[0:12] 7 fmt.Printf("类型:%T , 地址:%v ,第0个值的类型:%T , 第0个的值:%v, 地址: %v \n", slice, &slice, slice[0], slice[0], &slice[0]) 8 fmt.Printf("str1 = %v, 地址是:%v \n\n", str1, &str1) // 字符串转换切片是值拷贝 9 // 字符串本身也是byte数组,所以也可以进行切片 10 slice0 := str1[6:] 11 fmt.Println("slice0= ", slice0) 12 // slice0[0] = byte(97) // 这里会报错,不允许赋值 13 fmt.Println("str1= ", slice0[0]) 14 15 // 数组切片 16 var arr [5]int = [...]int{1, 2, 3, 4, 5} 17 var slice1 = arr[1:3] // slice1属于引用.&slice1[0]=&arr[1] 18 fmt.Println("slice1:", slice1, " &slice1[0]", &slice1[0], " \narr:", arr, " &arr[1]:", &arr[1]) 19 fmt.Println("切片的长度:", len(slice1)) 20 fmt.Println("切片的容量:", cap(slice1)) 21 22 // make()内置函数来创建切片 23 // 语法: var sliceName []type = make([]type,len,[cap]) 24 var slice2 []float64 = make([]float64, 5, 10) 25 slice2[1] = 20 // 默认值0 26 slice2[4] = 30 27 fmt.Println("slice2=", slice2) // slice2= [0 20 0 0 30] 28 fmt.Printf("slice2 len=%v cap=%v, sizeof=%v \n", len(slice2), cap(slice2), unsafe.Sizeof(slice2)) // slice2 len=5 cap=10, sizeof=24 29 30 // 定义一个数组直接初始化一个切片 31 var slice3 []int32 = []int32{1, 3, 4} 32 fmt.Println("slice3=", slice3) // slice3= [1 3 4] 33 fmt.Printf("slice3 len=%v cap=%v, sizeof=%v \n", len(slice3), cap(slice3), unsafe.Sizeof(slice3)) // slice3 len=3 cap=3, sizeof=24 34 35 // 切片的遍历和数组一致 36 // 切片初始化 37 var slice4 = arr[0:3] 38 var slice5 = arr[2:] 39 var slice6 = arr[:] 40 fmt.Println("slice4=", slice4) 41 fmt.Println("slice5=", slice5) 42 fmt.Println("slice6=", slice6) 43 // 切片之后还可以继续切片 44 slice7 := slice4[1:2] // slice7改动arr和slice4同样会改动(因为他们指向的内存是同一个) 45 fmt.Println("切片之后还可以继续切片=", slice7) 46 47 var slice8 []int 48 // 切片没有初始化是没办法使用的 49 fmt.Printf("slice8 Type=%T , len=%v , cap=%v , values=%v \n", slice8, len(slice8), cap(slice8), slice8) // slice8 Type=[]int , len=0 , cap=0 , values=[] 50 slice8 = append(arr[:], 100) 51 fmt.Printf("slice8 Type=%T , len=%v , cap=%v , values=%v \n", slice8, len(slice8), cap(slice8), slice8) 52 slice8 = append(slice8, 101) 53 fmt.Printf("slice8 Type=%T , len=%v , cap=%v , values=%v \n", slice8, len(slice8), cap(slice8), slice8) 54 55 var arr1 [5]int32 = [5]int32{1, 2, 3, 4, 5} 56 fmt.Printf("arr1 的值:%v , &arr1[0]=%v , &arr1[1]=%v , &arr1[2]=%v , &arr1[3]=%v , &arr1[4]=%v \n\n", arr1, &arr1[0], &arr1[1], &arr1[2], &arr1[3], &arr1[4]) 57 slice9 := arr1[:] 58 fmt.Printf("slice9 的值:%v, slice9 len=%v , slice9 cap =%v , &slice9[0]=%v , &slice9[1]=%v , &slice9[2]=%v , &slice9[3]=%v , &slice9[4]=%v \n\n", 59 slice9, len(slice9), cap(slice9), &slice9[0], &slice9[1], &slice9[2], &slice9[3], &slice9[4]) 60 slice10 := append(slice9, 6) // append之后返回的是新切片,已经和原来的arr1完全没有关系了 61 fmt.Printf("slice10 的值:%v, slice10 len=%v , slice10 cap =%v , &slice10[0]=%v , &slice10[1]=%v , &slice10[2]=%v , &slice10[3]=%v , &slice10[4]=%v \n\n", 62 slice10, len(slice10), cap(slice10), &slice10[0], &slice10[1], &slice10[2], &slice10[3], &slice10[4]) 63 // 只有切片可以copy. copy是值拷贝。长度不一致也可以copy 64 var slice11 []int32 = make([]int32, 10) 65 copy(slice11, slice9) // slice11[0] 的地址: 0xc0000202d0 , 值=[1 2 3 4 5 0 0 0 0 0] 66 fmt.Printf("只有切片可以copy slice11[0] 的地址: %v , 值=%v \n\n", &slice11[0], slice11) 67 var slice12 []int32 = make([]int32, 1) 68 copy(slice12, slice9) // slice12[0] 的地址: 0xc00001c2d4 , 值=[1] 69 fmt.Printf("只有切片可以copy slice12[0] 的地址: %v , 值=%v \n\n", &slice12[0], slice12) 70 }