Golang 错误处理丶数组丶切片丶随机数

发布时间 2023-09-12 09:35:47作者: 看一百次夜空里的深蓝

一.错误处理

 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 }