Go-13 Golang语言函数详解之内置函数panic、recover 的基本使用 和 defer、panic、recover三者结合使用进行异常处理

package main

import (
	"errors"
	"fmt"
)

/*	Golang语言函数详解之内置函数panic、recover的基本使用和defer、panic、recover结合使用进行异常处理	*/
/*
	defer、panic、recover 的使用规则记住下面三点:
		1. recover()函数必须搭配defer一块使用。
		2. defer 一定要在可能引发panic的语句之前定义。
		3. panic() 可以在任何地方使用。


	内置函数	:	作用
	close			主要用来关闭channel
	len				用来求长度,比如string、array、slice、map、channel
	new				用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针
	make			用来分配内存,主要用来分配引用类型,比如chan、map、slice
	append			用来追加元素到数组、slice中
	panic和recover	用来做错误处理
	Go 语言中目前Go1.12是没有异常机制,但是使用panic/recover模式来处理错误。panic可以在任何地方引发,但recover只有在defer调用的函数中有效。
	首先来看一个例子:
	1. panic()函数 的基本使用
	2. recover()函数 的基本使用
	3. defer、recover 实现异常处理
	4. defer、panic、recover 抛出异常

*/

func funcA() {
	fmt.Println("func A")
}

func funcB() {
	panic("panic in B")
}

func funcC() {
	fmt.Println("func C")
}

// defer、panic、recover 三者结合使用处理异常
func funcD() {
	defer func() {
		err := recover()
		// 如果程序出现了panic错误,可以通过recover恢复过来
		if err != nil {
			fmt.Println("execute this recover in D")
		}
	}()
	panic("panic in D")
}

// 3. defer、recover 实现异常处理
func fntwo() {
	defer func() {
		err := recover() // 下面的除法运算有分母为0的异常,此处结合recover函数,实现异常处理,不会让程序崩掉。
		if err != nil {
			fmt.Println("抛出异常给管理员发送邮件") // 这个会执行
			fmt.Println(err)                        // 会把捕获到的异常原因在此处打印,原因是 runtime error:integer divide by zero
		}
	}()

	num1 := 10
	num2 := 0
	res := num1 / num2
	fmt.Println("look this res=", res) // 这个地方分母为0,不符合要求,是一个异常。res := num1 / num2报错,此处不会执行,程序会跳转到上面的defer func(){}()函数定义那里
}

// 4. defer、panic、recover 三者结合使用处理异常
func readFileName(fileName string) error {
	if fileName == "main.go" {
		return nil
	}
	return errors.New("读取文件错误")
}

func fn3() {
	// 这里面和上面的funcD()函数中defer、recover、panic用法相同,funcD是流水线代码,理解起来更直观。
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("犯错啦,就要给你的上司发送邮件督促你啦")
		}
	}()

	var err = readFileName("niriliya.go")
	// 调用这个函数入参不符合if条件,会返回erros.New(“读取文件错误”),另外这个erros.New()函数的返回值查看源码可知只有一个参数来接收
	// 下面的if条件成立,会执行
	if err != nil {
		panic(err) // 这里用panic + 上面的 recover 来做readFileName()函数的错误处理。
	}
	fmt.Println("继续执行吧,皮卡丘")
}
func main() {
	// 1. panic()函数的基本使用
	funcA()
	//funcB()
	funcC()
	/*	执行结果是:
		func A
		panic: panic in B

		goroutine 1 [running]:
		main.funcB(...)
				C:/Users/Zhaoshan.lu/go/DaDi/15.go:24
		main.main()
				C:/Users/Zhaoshan.lu/go/DaDi/15.go:34 +0x66
		exit status 2
		注意:我们在funcB()函数中加了panic()导致程序崩溃,异常退出了。这个时候我们就可以通过recover()将程序恢复回来,继续往后执行。

	*/
	// 2. recover()函数的基本使用
	// 注意这个规则: 【【  panic可以在任何地方引发,但recover只有在defer调用的函数中有效。  】】
	funcD() // 执行这个的时候,先注释一下上面的funcB()函数,因为funcB()函数有panic异常会直接结束程序的运行就走不到这里,看不到效果了。
	fmt.Println()
	/*	执行结果是:
		func A
		func C
		execute this recover in D

		注意下面两个固定的规则:
			1. recover()必须搭配在defer调用的函数中使用。
			2. defer 一定要在可能引发panic的语句之前定义。
	*/
	// 3. defer、recover 实现异常处理
	fntwo()
	fmt.Println()
	/*	执行结果是:
		func A
		func C
		execute this recover in D

		抛出异常给管理员发送邮件
		runtime error: integer divide by zero
	*/

	// 4. defer、panic、recover 抛出异常
	fn3()
	fmt.Println()
	/*	执行结果是:
		func A
		func C
		execute this recover in D

		抛出异常给管理员发送邮件
		runtime error: integer divide by zero

		犯错啦,就要给你的上司发送邮件督促你啦

	*/

}



posted @ 2022-12-09 15:11  大海一个人听  阅读(155)  评论(0编辑  收藏  举报