宕机
话说这是一个风和日丽的上午,拿到了外卖小哥送来的我最心爱的麻辣烫,我打开了因为昨天刚充了三毛钱电费而恢复了使用的电脑,登上了满是美女好友的微信,熟悉的声音马上响彻在了我这三百平米的卧室中,我这该死的魅力,点开这闪烁的美女头像,一行文字映入眼帘,项目出bug了,直接宕机了,五分钟处理了,不然麻辣烫给你倒了…… 真好
跑题了……废话不多说,上货
啥是宕机
我认为go语言中的宕机和报错差不多,数组访问越界、空指针引用等,这些运行时错误都会引起宕机,宕机后程序就会停止,编译器就会输出对应的报错信息,包括 panic value 和函数调用的堆栈跟踪信息,panic value 通常是某种错误信息 看上去宕机好像没什么好处,但其实有时合理的宕机是一种非常明智的止损方式。
手动触发宕机
类似其他语言,比如java手动 throw 一个 error 一样,Go也有手动触发宕机的方式——panic()
packagemainimport"fmt"funcmain(){//xxxxxxxfmt.Println("我上面有一万行代码")panic("一万行也没用,我出毛病了")fmt.Println("我不好使了")}
Go语言程序在宕机时,会将堆栈和 goroutine 信息输出到控制台,所以宕机也可以方便地知晓发生错误的位置。上面就展示第7行发生了错误
如果我们想让方法最后宕机,不导致其他语句的执行可以使用defer
packagemainimport"fmt"funcmain(){//xxxxxxxfmt.Println("我上面有一万行代码")deferpanic("一万行也没用,我出毛病了")fmt.Println("哎,我又好使了")}
为什么会有两个错误信息呢,因为defer会在当前行加载,所以产生了第一次报错,后在方法后进行执行,产生了第二个报错。
宕机恢复
如果我们想在宕机后仍让程序继续执行,可以使用recover ,跟java中try/catch作用差不多,recover 仅在延迟函数 defer 中有效,在正常的执行过程中,调用 recover 会返回 nil 并且没有其他任何效果,如果当前的 goroutine 陷入恐慌,调用 recover 可以捕获到 panic 的输入值,并且恢复正常的执行。
packagemainimport"fmt"functest(){deferfunc(){err:=recover()iferr!=nil{fmt.Println("我说好使了你信不信")}}()//调用匿名函数demo()}funcdemo(){fmt.Println("一万行也没用,我出毛病了,下面都不好使")deferpanic("我还能说啥,说啥都不好使了")}funcmain(){//xxxxxxxfmt.Println("我上面有一万行代码")test()fmt.Println("哎,我又好使了")}
panic 和 recover 的组合有如下特性: 有 panic 没 recover,程序宕机。 有 panic 也有 recover,程序不会宕机,执行完对应的 defer 后,从宕机点退出当前函数后继续执行。
ps
虽然 panic/recover 能模拟其他语言的异常机制,但并不建议在编写普通函数时也经常性使用这种特性 在 panic 触发的 defer 函数内,可以继续调用 panic,进一步将错误外抛,直到程序整体崩溃 如果想在捕获错误时设置当前函数的返回值,可以对返回值使用命名返回值方式直接进行设置
你以为结束了
搞明白了如何恢复宕机的我拿着recover直接将导致宕机的方法捕捉,然后上去就是一顿乌鸦坐飞机,这回大功告成,赶紧回复处理完了 不一会收到回复,写的什么玩意,你就这么处理的嘛,留的坑给谁填,不仅这个月麻辣烫没了,下个月也没了 真是美好的一天……
大家看完发现有什么错误,写在下面吧!跟我黑虎阿福比划比划!