GO语言Error处理
Go语言没有提供像Java、C#、Python语言中的try...catch异常处理方式,而是通过函数返回值逐层往上抛。好处就是避免漏掉本应处理的错误。坏处是代码啰嗦。
错误与异常区别
错误指的是可能出现问题的地方出了问题,比如打开文件失败。
异常是不应该出现问题的地方出了问题,比如空指针。
Go中的错误是一种类型,错误用内置的error类型(接口)来表示。错误可以存储在变量中,从函数中返回。
type error interface {
Error() string
}
创建自定义错误
创建自定义错误可用errors包下的New()函数以及fmt包下的Errorf()函数。
//创建一个error的数据
err1 := errors.New("自己创建...")
fmt.Println(err1)
fmt.Printf("%T\n", err1) //*errors.fundamental
//创建一个error方法
err2 := fmt.Errorf("错误码:%d", 10000)
fmt.Println(err2) //错误码:10000
fmt.Printf("%T\n", err2) //*errors.errorString
自定义错误示例
//求矩形面积
type areaError struct {
msg string //错误描述
length float64 //矩形长度
wigth float64 //矩形宽度
}
func (e *areaError) Error() string {
return e.msg
}
func (e *areaError) lengthNegative() bool {
return e.length < 0 //如果比0小,返回false
}
func (e *areaError) wigthNegative() bool {
return e.wigth < 0 //如果比0小,返回false
}
func revArea(length, wigth float64) (float64, error) {
msg := ""
if length < 0 {
msg = "长度小于0"
}
if wigth < 0 {
if msg == "" {
msg = "宽度小于0"
} else {
msg += ",宽度小于0"
}
}
if msg != "" {
return 0, &areaError{msg, length, wigth}
}
return length * wigth, nil
}
func main() {
length, wigth := -4.3, -6.7
area, err := revArea(length, wigth)
if err != nil {
fmt.Println(err)
//断言判断具体error
if err, ok := err.(*areaError); ok {
if err.lengthNegative() {
fmt.Printf("error:长度,%.2f小于0\n", err.length)
}
if err.wigthNegative() {
fmt.Printf("error:宽度,%.2f小于0\n", err.wigth)
}
}
return
}
fmt.Println("矩形面积是:", area)
}
输入:
长度小于0,宽度小于0
error:长度,-4.30小于0
error:宽度,-6.70小于0
panic/recover
GO可以使用panic/recover模式来处理错误。 panic可以在任何地方引发,但recover只有在defer调用的函数中有效。
等到包含defer语句的函数执行完毕时,延迟函数(defer后的函数)才会被执行,而不管包含defer语句的函数是通过return的正常结束,还是由于panic导致的异常结束,你可以在一个函数中执行多条 defer语句,它们的执 行顺序与声明顺序相反。
panic:
- 内建函数
- 假如函数F中书写了panic语句,会终止其后要执行的代码,在panic所在函数F内如果存在要执行的defer函数列表,按照defer的逆序执行
- 返回函数F的调用者G,在G中,调用函数F语句之后的代码不会执行,假如函数G中存在要执行的defer函数列表,按照defert的逆序执行,这里的 defer有点类似 try-catch-finally中的finally
- 直到 goroutine整个退出,并报告错误
recover
- 内建函数
- 用来控制一个goroutine的panicking行为,捕获panic,从而影响应用的行为
- 一般的调用建议:在defer函数中,通过recever来终止一个goroutine的 panicking过程,从而恢复正常代码的执行;可以获取通过panic传递的 error
简单来讲go中可以抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理.
实例
func a() {
fmt.Println("func a")
}
func b() {
panic("func b")
}
func c() {
fmt.Println("func c")
}
func main() {
a()
b()
c()
}
执行到func b的时候会抛出异常,程序崩溃,可以使用recover将程序恢复
func a() {
fmt.Println("func a")
}
func b() {
defer func() {
err := recover()
if err != nil{
fmt.Println("recover fun b")
}
}()
panic("func b")
}
func c() {
fmt.Println("func c")
}
func main() {
a() //func a
b() //recover fun b
c() //func c
}
- recover()必须搭配defer使用。
- defer一定要在可能引发panic的语句之前定义。
GO语言Error处理的更多相关文章
- 不一样的go语言-error
前言 go语言的error处理方式,在目前流行的编程语言中属于刺头.似乎天生就是用来有别于他人标记.TIOBE排行榜全十除了C语言,无一例外是try catch的阵营.而排在go之前的语言除了C与 ...
- c语言 error C4996: 'strupr': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
问题: 在使用visual studio 2013,进行调试执行代码时,出现如下错误: error C4996: 'strupr': The POSIX name for this item is d ...
- c语言-error C2440: “static_cast”: 无法从“UINT (__thiscall CHyperLink::* )(CPoint)”转换为“LRESULT (__thiscall CWnd::* )(CPoint)”
出现这个错误的原因可是“人力不可抗拒”之原因造成的,因为旧版本的 ON_WM_NCHITTEST 宏使用了 UINT (__thiscall CWzButton::* )(CPoint); 类型的类成 ...
- 07. Go 语言接口
Go 语言接口 接口本身是调用方和实现方均需要遵守的一种协议,大家按照统一的方法命名参数类型和数量来协调逻辑处理的过程. Go 语言中使用组合实现对象特性的描述.对象的内部使用结构体内嵌组合对象应该具 ...
- golang error错误处理
error定义 数据结构 go语言error是一普通的值,实现方式为简单一个接口. // The error built-in interface type is the conventional i ...
- flask框架(二):简单的登录demo
一:main.py # -*- coding: utf-8 -*- # @Author : Felix Wang # @time : 2018/7/3 22:58 from flask import ...
- 3_JSP
一. 引言 1.1 现有问题 在之前学习Servlet时, 服务器通过Servlet响应客户端页面, 有什么不足之处? 开发方式麻烦: 继承父类, 覆盖方法, 配置web.xml或注解 代码修改麻烦: ...
- [转载]VS2012编译C语言scanf函数error的解决方法
在VS 2012 中编译 C 语言项目,如果使用了 scanf 函数,编译时便会提示如下错误: error C4996: 'scanf': This function or variable may ...
- 与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence
遇到的问题 在一个与Ruby语言对接的项目中,决定使用RSA算法来作为数据传输的加密与签名算法.但是,在使用Ruby生成后给我的私钥时,却发生了异常:IOException: algid parse ...
随机推荐
- js实现图片上传本地预览
演示地址:https://xibushijie.github.io/static/uploadImg.html <!DOCTYPE> <html> <head> & ...
- 安装xadmin模板依赖
### 安装xadmin模板依赖sudo pip3 install django-crispy-forms django-formtools django-import-export django-r ...
- Python开发之路:目录篇
第一部分:Python基础知识 本篇主要python基础知识的积累和学习,其中包括python的介绍.基本数据类型.函数.模块及面向对象等. 第一篇:Python简介 第二篇:Python基本知识 ...
- APS实现的要点与难点
在前一篇关于文章中讨论了不同层级.粒度的生产计划,在各行业中受重视程度的差异问题. 承蒙大家热烈讨论.本文则在收集各方高见的基础上,对于供应链上各个环节的运营.生产计划再作稍微深入一点的探讨.本文将列 ...
- Alpha冲刺随笔七:第七天
课程名称:软件工程1916|W(福州大学) 作业要求:项目Alpha冲刺(十天冲刺) 团队名称:葫芦娃队 作业目标:在十天冲刺里对每天的任务进行总结. 随笔汇总:https://www.cnblogs ...
- python实现Bencode解码方法
近期搞项目中遇到Bencode解码的问题,就用Py写了个Bencode解码的代码.作为笔记保存参考. BEncoding是BitTorrent用在传输数据结构的编码方式,这种编码方式支持四种类型的数据 ...
- test20190802 夏令营NOIP训练18
今天的题很有难度啊.然而我10:40才看题-- 高一学堂 在美丽的中山纪念中学里面,有一座高一学堂.所谓山不在高,有仙则名:水不在深,有龙则灵.高一学堂,因为有了yxr,就成了现在这个样子 = =. ...
- flask框架下读取mysql数据 转换成json格式API
研究了一天 因为需要从数据库拿数据然后转换成json的格式 expose出去为 API 发现一条数据是容易,两条以上我居然搞了这么久 好歹出来了 先贴一下 后面更新 mysql的操作 比较容易了htt ...
- Oracle-分析函数之取上下行数据lag()和lead()
这两个函数是偏移量函数,可以查出一个字段的上一个值或者下一个值,配合over来使用. lead函数,这个函数是向上偏移. lag函数是向下偏移一位. 语法 [语法] lag(EXPR,<OFFS ...
- C语言蓝桥杯比赛原题和解析
蓝桥杯:在计算机编程领域,是具有一定含金量的竞赛,用于选拔信息技术人才. 一般分为多个领域,其中包含了C/C#/C++/Java/Python等编程语言的测试题,多为算法的设计题. 下面,在搜题过程中 ...