【第二十六篇】Go 错误处理机制🔥🔥

120 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

一、错误处理:

看一段代码:

package main

import "fmt"

func test() {
	num1 := 10
	num2 := 0
	res := num1 / num2
	fmt.Println("res=", res)
}
func main() {

	// 测试:
	test()
	fmt.Println("main()下面的代码 ......")

}

对上面代码的总结:

  1. 在默认情况下,当发生错误后(pamic),程序就会退出(崩溃)
  2. 如果我们希望,当发生错误后,可以捕获到错误,并进行处理,保证程序可以继续向下执行。还可以在捕获到错误后,给管理员一个提示(邮件、短信.....)
  3. 这里引出我们要讲的错误处理机制

二、基本说明:

  1. Go 语言追求的简洁优雅,所以,Go 语言不支持传统的 try .... catch .... finally 这种处理。
  2. Go 中引用的处理方式:defer,panic ,recover
  3. 这几个异常的使用场景可以这么简单描述:Go 中可以抛出一个 panic 的异常,然后在 defer 中通过 recover 捕获这个异常,然后正常处理。

一、使用 defer + recover 来处理错误:

package main

import (
	"fmt"
	"time"
)

func test() {

	// 使用 defer + recover 来捕获和处理异常
	defer func() {
		err := recover() // recover ()内置函数,可以捕获到异常
		if err != nil {  // 说明捕获到错误
			fmt.Println("err=", err)
		}
	}()

	num1 := 10
	num2 := 0
	res := num1 / num2
	fmt.Println("res=", res)
}
func main() {

	// 测试:
	test()
	fmt.Println("main()下面的代码 ......")
	time.Sleep(time.Second)

}


二、错误处理的好处:

进行错误处理后,程序不会轻易的挂掉,如果加入预警代码,就可以让程序更加健壮。看一个案例演示:

package main

import (
	"fmt"
	"time"
)

func test() {

	// 使用 defer + recover 来捕获和处理异常
	defer func() {
		err := recover() // recover ()内置函数,可以捕获到异常
		if err != nil {  // 说明捕获到错误
			fmt.Println("err=", err)
			// 这里就可以将错误信息,发送给管理员....
			fmt.Println("发送邮件到xxxxx")
		}
	}()

	num1 := 10
	num2 := 0
	res := num1 / num2
	fmt.Println("res=", res)
}
func main() {

	// 测试:
	test()
	fmt.Println("main()下面的代码 ......")
	time.Sleep(time.Second)

}


三、自定义错误:

Go 程序中,也支持自定义错误,使用 errors.New 和 panic 内置函数。

  1. errors.New(“错误说明”),会返回一个 error 类型的值,表示一个错误。
  2. panic 内置函数,接收一个 interface() 类型的值(也就是任何值了)作为参数。可以接收 error 类型的变量、输出错误信息,并退出程序。
package main

import (
	"errors"
	"fmt"
)

func test() {

	// 使用 defer + recover 来捕获和处理异常
	defer func() {
		err := recover() // recover ()内置函数,可以捕获到异常
		if err != nil {  // 说明捕获到错误
			fmt.Println("err=", err)
			// 这里就可以将错误信息,发送给管理员....
			fmt.Println("发送邮件到xxxxx")
		}
	}()

	num1 := 10
	num2 := 0
	res := num1 / num2
	fmt.Println("res=", res)
}

// 函数去读取以配置文件 init.conf 的信息
// 如果文件名传入不正确,我们就返回一个自定义的错误
func readConf(name string) (err error) {
	if name == "config.ini" {
		// 读取..
		return nil
	} else {
		// 返回一个自定义错误
		return errors.New("读取文件错误.....")
	}
}

func test02() {

	err := readConf("config2.ini")
	if err != nil {
		// 如果读取文件发生错误,就输出这个错误,并终止程序
		panic(err)
	}
	fmt.Println("test02()继续执行....")
}
func main() {

	// // 测试:
	// test()
	// fmt.Println("main()下面的代码 ......")
	// time.Sleep(time.Second)

	// 测试自定义错误的使用
	test02()
	fmt.Println("main() 下面的代码.....")
}