Go最全Go-错误、异常处理详解_or volume label syntax is incorrect(4),Golang编程基础教程

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

总结

参考


错误

type error interface {
    Error() string
}

内建error接口类型是约定用于表示错误信息,nil值表示无错误。

获取error信息

	_, err := os.Create("./.??")
	if err != nil{
		fmt.Printf("%v %T\n",err,err)
		fmt.Println(err.Error())
	}

结果

open ./.??: The filename, directory name, or volume label syntax is incorrect. *fs.PathError
open ./.??: The filename, directory name, or volume label syntax is incorrect.

源代码

src->os->error.go

type PathError = fs.PathError

src->io->fs->fs.go

type PathError struct {
	Op   string
	Path string
	Err  error
}

func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }

func (e *PathError) Unwrap() error { return e.Err }

func (e *PathError) Timeout() bool {
	t, ok := e.Err.(interface{ Timeout() bool })
	return ok && t.Timeout()
}

PathError是结构体实现了error接口,可以看到结果和源代码的格式一样

error统一定义

errors包有

func New(text string) error

使用字符串创建一个错误

部分朋友一样的错误,每次都New,例如,errors.New(“b can not be zero”)、errors.New(“division by zero”)、errors.New(“division by zero!!!”)

我们应该学习go的开发者们的写法,将error统一定义,如果比较多,可以单独写一个文件(例如,errors.go)放在包中,比较少的话可以写在本文件

var divisionByZeroError = errors.New("division by zero")

error放在返回值类型列表的最后

约定的写法,一般都是放在最后,建议大家这样写

func division(a,b int) (int,error) {
	if b == 0{
		return 0,divisionByZeroError
	}
	return a/b,nil
}

多次尝试可避免失败,不必立即返回error

这个常见的情况就是写爬虫,由于网络原因,导致连接失败,一般情况下都是用户传一个重试次数retries,或者超时时间timeout,达到条件时才会返回错误或抛出异常。

多层嵌套,给error添加日志/出错位置

go的标准库的日志不是很强大,这里就不展示日志了,可以标出出错位置

func positionError(file,line string,err error) error {
	return errors.New(file+" "+ line + ":"+err.Error())
}

我们写一个正整数除法,调用前面的函数(有修改,查看全部代码)

func cal(a,b int) (int,error) {
	if a<=0 || b<0{
		return 0,positionError("err.go","28",negativeError)
	}
	return division(a,b)
}
	_, err = cal(3, 0)
	fmt.Println(err)
	_,err = cal(-3,3)
	fmt.Println(err)

结果

err.go 20:division by zero
err.go 28:calculate negative number

异常

有时程序出错是不可控的或很难判断的,如数组越界、空指针,这是就需要用到panic

panic

func panic(v interface{})

内建函数panic停止当前goroutine的正常执行。当函数F调用panic时,F的正常执行就会立刻停止。F中defer的所有函数先入后出执行后,F返回给其调用者G。G如同F一样行动,层层返回,直到该Go程中所有函数都按相反的顺序停止执行。之后,程序被终止,而错误情况会被报告,包括引发该panic的实参值,此终止序列称为panic过程。

// 使用panic
func cal2(a,b int) (int,error) {
	if a<=0 || b<0{
		panic("cannot use negative number")
	}
	return division(a,b)
}

结果

panic: cannot use negative number

goroutine 1 [running]:
main.cal2(0x1, 0xffffffffffffffff, 0xc0000d5f28, 0x1, 0x1)
        E:/Workspace/Go_workspace/learn_go/src/learnerr/main/err.go:36 +0x8a
main.main()
        E:/Workspace/Go_workspace/learn_go/src/learnerr/main/err.go:52 +0x2af
exit status 2

recover

有时异常是我们意料之外的,需要进行恢复,不影响后序程序的执行,这时,就需要recover

func recover() interface{}

内建函数recover允许程序管理panic过程中的goroutine。在defer的函数中,执行recover调用会取回传至panic调用的错误值,恢复正常执行,停止恐慌过程。若recover在defer的函数之外被调用,它将不会停止panic过程序列。在此情况下,或当该goroutine不在panic过程中时,或提供给panic的实参为nil时,recover就会返回nil。

func cal2(a,b int) (int,error) {
	if a<=0 || b<0{
		panic("cannot use negative number")
	}
	err := recover()
	fmt.Println(err)
	if err != nil{
		return 0,err.(error)
	}
	return division(a,b)
}
	res,err := cal2(1,-1)
	fmt.Println(res)

结果

panic: cannot use negative number

goroutine 1 [running]:
main.cal2(0x1, 0xffffffffffffffff, 0xc0000d5f28, 0x1, 0x1)
        E:/Workspace/Go_workspace/learn_go/src/learnerr/main/err.go:37 +0x185
main.main()
        E:/Workspace/Go_workspace/learn_go/src/learnerr/main/err.go:59 +0x2bb
exit status 2

可见,不在defer 的函数中使用recover是没有意义的

修改到defer的函数中

func cal2(a,b int) (int,error) {
	defer func() {
	if err := recover();err!=nil{
		fmt.Println(err)
		}
	}()
	if a<=0 || b<0{
		panic("cannot use negative number")
	}
	return division(a,b)
}

结果:

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

存中…(img-CqQXlv3e-1715503773834)]
[外链图片转存中…(img-qLQtwaHA-1715503773834)]
[外链图片转存中…(img-unEMlNUb-1715503773835)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 8
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值