golang error panic

Go 没有像 Java 和 .NET 那样的 try/catch 异常机制:不能执行抛异常操作。但是有一套 defer-panic-and-recover 机制(这个机制还可以)

Go 的设计者觉得 try/catch 机制的使用太泛滥了,而且从底层向更高的层级抛异常太耗费资源。他们给 Go 设计的机制也可以“捕捉”异常,但是更轻量,并且只应该作为(处理错误的)最后的手段。

Go 是怎么处理普通错误的呢?通过在函数和方法中返回错误对象作为它们的唯一或最后一个返回值——如果返回 nil,则没有错误发生——并且主调 (calling) 函数总是应该检查收到的错误。(设计者脑子被门挤了,这个非常恶心,难受死了,我想给他一套闪电五连鞭顺便扔棉碑去)

Go 检查和报告错误条件的惯有方式:

  • 产生错误的函数会返回两个变量,一个值和一个错误码;如果后者是 nil 就是成功,非 nil 就是发生了错误。(这个设定非常恶心,要老命了,其实很多语言都会有这个问题,比如java为了避免空指针而判断是否为null)
  • 为了防止发生错误时正在执行的函数(如果有必要的话甚至会是整个程序)被中止,在调用函数后必须检查错误。
// 对开发来说是痛苦的,每次都要判断,如果能统一catch肯定是会更加方便的
if err != nil 
// 自定义error信息
var errNotFound error = errors.New("Not found error")

当发生像数组下标越界或类型断言失败这样的运行错误时,Go 运行时会触发运行时 panic,伴随着程序的崩溃抛出一个 runtime.Error 接口类型的值。这个错误值有个 RuntimeError() 方法用于区别普通错误

panic() 可以直接从代码初始化:当错误条件(我们所测试的代码)很严苛且不可恢复,程序不能继续运行时,可以使用 panic() 函数产生一个中止程序的运行时错误。panic() 接收一个做任意类型的参数,通常是字符串,在程序死亡时被打印出来。Go 运行时负责中止程序并给出调试信息。

个人感觉类似于java中的throw new RuntimeException("xxxxxxxx")

// 报错了,程序终止不会往下走了
panic("A severe error occurred: stopping the program!")

panic和defer以及recover联合使用。需要注意 recover(感觉跟java的catch一样) 只能在 defer(相当于java的finally,但是这里配合recover使用起来和java不太一样) 修饰的函数中使用:用于取得 panic() 调用中传递过来的错误值,如果是正常执行,调用 recover() 会返回 nil,且没有其它效果。

这个机制,挺好玩的,属于语法糖,但是if error != nil依旧痛苦

var errNotFound error = errors.New("Not found error")

func TestError() {
	fmt.Println("Starting the program")
	protect(func() {
		panic(errNotFound)
	})
	fmt.Println("Ending the program")
}

func protect(g func()) {
	defer func() {
		log.Println("done")
		// Println executes normally even if there is a panic
		if err := recover(); err != nil {
			log.Printf("run time panic: %v", err)
		}
	}()
	log.Println("start")
	g() //   possible runtime-error
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>