go语言学习-异常处理

1、异常场景

  • 网络故障
  • 硬件故障
  • 组件故障
  • 输入错误
  • 逻辑错误
  • 链路调度错误

2、异常处理方式

# python或者java异常处理
try 
	可能出现的错误
catch
	对错误进行处理 
xxx,err := 代码
if err != nil {
	代码出现错误,需要做处理
}

3、自定义错误

有两种方法:1、通过errors包中的errors.New方法定义。 2、通过fmt.Errorf方法定义错误。

package main

import (
	"errors"
	"fmt"
)

// 定义一个函数,用来实现除法
func division(i1, i2 float64) (res float64, err error) {
	fmt.Println("需要计算的数字是:", i1, i2)
	if i2 == 0 {
		return 0, errors.New("输入的分母不能为0")
	} else {
		res = i1 / i2
		return res, nil
	}
}

func main() {
	// go 错误定义为一种类型,err = ccc
	// 像使用其他类型的变量一样,去处理我们的错误。
	// go打开一个本地文件。
	// 1. 打开这个文件 文件不存在  没有权限
	// 2. 写入内容/读取内容
	// f, err := ioutil.ReadFile("./text.txt")
	// if err != nil {
	// 	// 此时readfile报错,出现了问题
	// 	fmt.Println("读取文件内容失败:", err.Error())
	// } else {
	// 	fmt.Println(string(f))
	// }
	// 自定义err
	err := errors.New("这是一个自定义错误")
	fmt.Println(err)
	err2 := fmt.Errorf("这是一个自定义错误: %s,它是使用fmt生成的", "这是错误内容")
	fmt.Println("这是一个使用fmt定义的错误:", err2.Error())
	// var
	res, err3 := division(2, 0)
	if err3 != nil {
		fmt.Println("计算错误:", err3.Error())
	} else {
		fmt.Println("计算结果:", res)
	}
}

4、程序异常终止

4.1 程序终止panic

panic:可以在异常的时候让程序终止执行,退出程序。或者是程序所强依赖的基础组件不可用。
此时程序已经无法继续正常工作,此时可以使用panic抛出异常,并且把程序退出。
切记:panic不能滥用,不能到处使用panic

package main

import (
	"errors"
	"fmt"
	"time"
)

// 实现数据库的链接
func connectDatabase(address string, port int) (string, error) {
	// 如果address和port为空
	if address == "" || port == 0 {
		return "", errors.New("无法链接数据库")
	} else {
		return "数据库链接成功", nil
	}
}

func main() {
	s, err := connectDatabase("", 0)
	for {
		time.Sleep(5 * time.Second)
		// 模式启动程序
		if err != nil {
			// 说明无法链接数据库
			fmt.Println(err)
			panic(err) // 就会退出程序
		} else {
			// 链接成功
			fmt.Println(s)
			// 正常启动程序
		}
	}
}

4.2 defer 程序退出收尾处理

defer: 是go语言中的一种延迟调用机制,defer里面的内容可以在函数return之前或者是程序panic之前执行。
一般用于资源回收和数据返回,defer也可以用于异常时的恢复。
defer是可以有多个的,采用先进后出的机制。

package main

import (
	"errors"
	"fmt"
)

// 实现数据库的链接
func connectDatabase(address string, port int) (string, error) {
	// 如果address和port为空
	if address == "" || port == 0 {
		return "", errors.New("无法链接数据库")
	} else {
		return "数据库链接成功", nil
	}
}

// 返回数据给前端
func returnDataToFrontend(msg string) {
	fmt.Println("返回给前端的数据是:", msg)
}

func main() {
	//比如一些常见的场景
	// 1. 关闭连接池
	// 2. 关闭文件句柄
	// 3. 记录一些异常日志
	msg := "返回给前端的数据"
	defer returnDataToFrontend("1")
	defer returnDataToFrontend("2")
	defer returnDataToFrontend("3")
	defer returnDataToFrontend("4")
	defer returnDataToFrontend(msg) // 不会真正的执行
	_, err := connectDatabase("", 0)
	if err != nil {
		fmt.Println(err)
		// ret
		panic(err)
	}
	// 返回数据给前端
	// returnDataToFrontend(msg)
}

5、异常捕获

package main

import "fmt"

func printSliceData(s []string) {
	// 使用recover进行异常捕获
	defer func() { // 匿名函数
		fmt.Println("程序执行失败, 捕获异常")
		if err := recover(); err != nil {
			// recover是用来捕获panic的报错的
			// 尝试恢复,防止程序异常退出
			fmt.Println("捕获到了一个错误:", err)
			// 发出一个告警
			// 记录一条日志
			// 返回给前端:说传入的值不对
		}
	}()
	fmt.Println("切片的内容:", s)
	// 打印一下切片的第三个值
	fmt.Println("切片的第三个值是:", s[2])
}

func main() {
	// recover 异常的捕获和处理
	//
	s := []string{"a", "b"}
	printSliceData(s)

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Studying!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值