011.错误与异常

文章详细介绍了Go语言中的错误处理,包括使用errors.New和fmt.Errorf声明错误,以及如何自定义错误。同时,文章讨论了异常(panic)的使用,如手动抛出panic,panic后的defer执行以及如何通过recover处理异常。
摘要由CSDN通过智能技术生成

目录

1.错误:

1.1 Go语言声明错误的两种方式

1.2 查看源码,学习如何自定义错误

1.3 自定义错误

2.异常 

2.1 Go语言中抛出异常

2.2 程序中触发了panic会终止后面的语句,defer语句还是会按倒序执行

2.3 使用defer执行匿名函数+recover处理异常


1.错误:

概念:程序运行过程中可能报错的代码,是可以预见的,需要手动处理

1.1 Go语言声明错误的两种方式

package main

import (
	"errors"
	"fmt"
)

/*
Go语言声明错误的两种方式
1.errors.New("错误描述")
2.fmt.Errorf("错误描述",错误码)
*/
func main() {
	//方式一
	err1 := errors.New("errors声明的错误")
	fmt.Printf("类型:%T,内容:%v\n", err1, err1)
	//方式二
	err2 := fmt.Errorf("fmt声明的错误,错误码:%d", 500)
	fmt.Printf("类型:%T,内容:%v\n", err2, err2)

	//errors实现年龄校验
	err3 := func(age int) error {
		if age < 0 {
			return errors.New("年龄不能小于0")
		}
		return nil
	}(-1)
	if err3 != nil {
		fmt.Printf("年龄校验不通过,原因:%v\n", err3)
	}
	//fmt实现性别校验
	err4 := func(gender string) error {
		if gender != "男" && gender != "女" {
			return fmt.Errorf("性别必须为男|女,code:%d", 500)
		}
		return nil
	}("未知")
	if err4 != nil {
		fmt.Printf("性别校验不通过,原因:%v\n", err4)
	}
}

1.2 查看源码,学习如何自定义错误

package main

import (
	"errors"
	"fmt"
	"net"
	"os"
)

/*
查看源码,学习自定义错误
*/
func main() {
	//打开文件方法
	file, err := os.Open("day11//note.txt1")
	if err != nil {
		fmt.Printf("文件打开失败,原因:%v\n", err) //文件打开失败,原因:open day11//note.txt1: no such file or directory
	} else {
		fmt.Printf("文件打开成功,文件名:%s\n", file.Name())
	}
	//根据域名查看ip地址方法
	host, err2 := net.LookupHost("www.baidu.com1")
	if err2 != nil {
		fmt.Println(err2) //lookup www.baidu.com1: no such host
		var dnsError *net.DNSError
		ok := errors.As(err2, &dnsError)
		if ok {
			if dnsError.IsTimeout {
				fmt.Println("超时错误")
			} else if dnsError.IsTemporary {
				fmt.Println("临时错误")
			} else if dnsError.IsNotFound {
				fmt.Println("地址错误") //地址错误
			} else {
				fmt.Println("其他错误")
			}
		}
	}
	fmt.Printf("域名访问成功,地址:%v", host)
}

1.3 自定义错误

package main

import (
	"errors"
	"fmt"
)

/*
	自定义错误
	1.自定义结构体
	2.实现error接口的Error()string方法,定义打印格式,
*/

type DiyError struct {
	Code int
	Msg  string
}

func (e *DiyError) Error() string {
	return fmt.Sprintf("{code:%d,msg:%s}", e.Code, e.Msg)
}

func main() {
	//自定义校验年龄方法,校验不通过,抛出自定义异常
	err := func(age int) error {
		if age < 0 {
			return &DiyError{500, "年龄不能小于0"}
		}
		return nil
	}(-1)
	if err != nil {
		fmt.Println(err)
		var diyError *DiyError
		ok := errors.As(err, &diyError)
		if ok {
			fmt.Printf("年龄校验不通过,原因:%s,错误码:%d", diyError.Msg, diyError.Code)
		}
	}
}

2.异常 

2.1 Go语言中抛出异常

/*
异常:代码运行过程中不可预见的报错,会抛出panic,针对代码中可能出现的panic可以recover处理panic
*/
func main() {
	//手动抛出异常
	panic("我是一个panic")
}

2.2 程序中触发了panic会终止后面的语句,defer语句还是会按倒序执行

/*
异常:代码运行过程中不可预见的报错,会抛出panic,模拟代码抛出panic
*/
func main() {
	defer fmt.Println("main-->1")
	defer fmt.Println("main-->2")
	fmt.Println("main-->3")
	test(-1)
	defer fmt.Println("main-->4")
	fmt.Println("main-->5")
}

func test(i int) {
	defer fmt.Println("test-->1")
	defer fmt.Println("test-->2")
	fmt.Println("test-->3")
	if i < 0 { //如果i<0,手动抛出一个panic,正常业务逻辑中可能就是代码自动抛出的
		panic("出现了panic")
	}
	defer fmt.Println("test-->4")
	fmt.Println("test-->5")
}

2.3 使用defer执行匿名函数+recover处理异常


func main() {
	defer fmt.Println("main-->1")
	defer fmt.Println("main-->2")
	fmt.Println("main-->3")
	test(-1)
	defer fmt.Println("main-->4")
	fmt.Println("main-->5")
}

func test(i int) {
	//最终代码执行完,不希望预见不到的异常抛出,可以使用defer执行匿名函数+recover处理
	defer func() {
		if msg := recover(); msg != nil {
			fmt.Println("recover处理了异常,msg:", msg)
		}
	}()
	defer fmt.Println("test-->1")
	defer fmt.Println("test-->2")
	fmt.Println("test-->3")
	if i < 0 { //如果i<0,手动抛出一个panic,正常业务逻辑中可能就是代码自动抛出的
		panic("出现了panic")
	}
	defer fmt.Println("test-->4")
	fmt.Println("test-->5")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值