Golang中error错误处理浅谈

  • 一.error与类型错误的变量进行比较
    • 1.== 比较
    • 2.contains 比较
  • 二.断言底层结构类型,并从结构体字段获取更多信息
  • 三.断言底层类型的行为

在解析了 Golang中error和创建error的源码后( Golang学习——error和创建error源码解析)。

对error有了一定理解,不过error处理才是实际开发中非常重要的一点。

Golang中的error处理是一门大学问,写出优雅又正确的处理代码是比较考验编码功底和知识广度,深度的。

今天就先浅谈一下Golang中的错误处理。

一.error与类型错误的变量进行比较

1.== 比较

直接进行比较也是一种方式,但是有种硬编码的感觉,必须事先确定好错误类型或已经知道要发生的错误是什么类型的,这样在错误比较的时候才能处理得当。

让我们通过一个例子来理解这个问题。

filepath包的Glob函数用于返回与模式匹配的所有文件的名称。当模式出现错误时,该函数将返回一个错误ErrBadPattern

filepath包中定义了ErrBadPattern,如下所述:

var ErrBadPattern = errors.New("syntax error in pattern")

errors.New()用于创建新的错误。模式出现错误时,由Glob函数返回ErrBadPattern

实战看一下就明白:

files, error := filepath.Glob("[")
if error != nil && error == filepath.ErrBadPattern {fmt.Println("error:", error)return
}
fmt.Println("matched files:", files)

输出:

error: syntax error in pattern

我们想返回一个匹配 “[” 模式的文件,如果发生错误会与我们预料中的错误类型进行 == 比较。如果比较为True,则对错误进行处理。

通过输出,我们看到 error 确实是syntax error in pattern

但是这种方式有个问题:就是这些错误,往往是提前约定好的,而且处理起来不太灵活。

不过最大的问题是引入了外部包,导致在定义 error 和使用 error 的包之间建立了依赖关系。比如实例中,就引入了path/filepath包。

当然这是标准库的包,还能接受。如果很多用户自定义的包都定义了错误,那我们就要引入很多包,来判断各种错误,这容易引起循环引用的问题。

不过这种比较的优点就是错误界限比较清楚,能够清晰的知道到底是什么错误

2.contains 比较

contains 这种方式的比较,是用字符串匹配的方式判断错误字符串里是不是出现了某种错误。
例子如下:

func openFile(path string) error {_, err := os.Open(path)if err != nil {return fmt.Errorf("cannot open file, err:", err)}return nil
}func main(){err := openFile("./test.txt")if strings.Contains(error.Error(), "not found") {// handle error}
}

这种处理方式,给人一种很模糊的感觉,而且代码风格怪怪的,error.Error() 是设计用来处理错误,结果是要写到文件或是打印出来,用上述方式比较则显得不规范。

二.断言底层结构类型,并从结构体字段获取更多信息

通过类型断言来判断error是哪种类型的错误,通常指的是那些实现了 error 接口的类型。

这些类型一般都是结构体,除了error字段外,还有其他字段,提供了额外的信息。

我们看一个实例:

type PathError struct {Op   stringPath stringErr  error
}func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }

上述代码是 PathError类型错误的定义及实现。
Error()方法拼接 操作路径实际错误 并返回它。这样我们就得到了错误信息。

我们验证一下这些字段的输出内容是什么:

f, err := os.Open("./test.txt")
if err, ok := err.(*os.PathError); ok {fmt.Printf("err.Op -> %s \n", err.Op)fmt.Printf("err.Path -> %s\n", err.Path)fmt.Printf("err.Err -> %v\n", err.Err)return
}
fmt.Println(f.Name(), "打开成功")

输出:

err.Op -> open
err.Path -> ./test.txt
err.Err -> The system cannot find the file specified.

通常,使用这样的 error 类型,外层调用者需要使用类型断言来判断错误。

不过错误发生并不一定是自己所希望的那样,具有意外性,如果考虑比较全面,想断言多种类型的错误然后一一处理,会使用很多if elseswitch case语句。

这样的做的话,无形中会导入很多外部的包,容易引起循环引用,不太推荐。

三.断言底层类型的行为

断言底层类型的行为,通常指的是调用struct类型的方法来获取更多信息。

举个例子,查看 DNSError 源码:

// DNSError represents a DNS lookup error.
type DNSError struct {Err         string // description of the errorName        string // name looked forServer      string // server usedIsTimeout   bool   // if true, timed out; not all timeouts set thisIsTemporary bool   // if true, error is temporary; not all errors set thisIsNotFound  bool   // if true, host could not be found
}func (e *DNSError) Timeout() bool { return e.IsTimeout }func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }

从上面的代码中可以看到,DNSError有两个方法Timeout()Temporary(),它们都返回一个布尔值,表示错误是超时还是临时的。

实战一下:

addrs, err := net.LookupHost("www.bucunzaide.com")if err != nil {if ins, ok := err.(*net.DNSError); ok {if ins.IsTimeout {fmt.Println("链接超时......")} else if ins.IsTemporary {fmt.Println("暂时性错误......")} else if ins.IsNotFound {fmt.Printf("链接无法找到......,err:%v\n", err)} else {fmt.Println("未知错误......", err)}}return
}
fmt.Println("访问成功,地址为:", addrs)

输出:

链接无法找到......,err:lookup www.bucunzaide.com: no such host

例子中随便造了一个域名,然后去访问,拿到网络请求返回的 error 后,我们去断言了错误类型,然后去判断是DNSError的哪种错误行为,这样我们就能知道请求错误发生的原因了。

这样做的好处是不需要 import 引用定义错误的包,因为判断就是结构体的方法(已经引用过包了),比较推荐这种方式。

总结一下,今天主要记录了处理错误的基本三种方式,以后还会一直跟进错误处理这个话题,学习了更好更优雅的处理方式后会再记录。

Golang学习——error错误处理浅谈相关推荐

  1. 深度学习 | BN层原理浅谈

    深度学习 | BN层原理浅谈 文章目录 深度学习 | BN层原理浅谈 一. 背景 二. BN层作用 三. 计算原理 四. 注意事项 为什么BN层一般用在线性层和卷积层的后面,而不是放在激活函数后 为什 ...

  2. linux mbr 分区表修复,备份/恢复MBR和分区表,以及无备份修复MBR及分区表错误;浅谈引导故障和分区方案...

    [原创]备份/恢复MBR和分区表以及无备份修复MBR和分区表错误,浅谈引导故障和分区方案.(完成66%) (这是我博客中的一篇文章,现在发到这里来) 手工备份/恢复MBR和分区表,以及无备份修复MBR ...

  3. 萌新学习的第一天-浅谈梳理自己对硬件局面的看法

    **浅谈目前对硬件局势的了解** 今天在阅读linux基础教程的同时把计算机的硬件知识重新系统复习了一次,对于硬件这方面我在之前就有些基础,但毕竟只是个人单方面的了解,对于一些细节还欠考虑,所以对于硬 ...

  4. python打开方式错误_浅谈python 调用open()打开文件时路径出错的原因

    昨晚搞鼓了一下python的open()打开文件 代码如下 def main(): infile =open("C:\Users\Spirit\Desktop\bc.txt",'r ...

  5. c lambda表达式 select 改变字段名称_大神是如何学习 Go 语言之浅谈 select 的实现原理...

    很多 C 语言或者 Unix 开发者听到 select 想到的都是系统调用,而谈到 I/O 模型时最终大都会提到基于 select.poll 和 epoll 等函数构建的 IO 多路复用模型,我们在这 ...

  6. 三层架构学习的困难_浅谈C/S和B/S架构的工作原理及优缺点

    C/S架构 一.C/S架构及其背景 C/S架构是一种比较早的软件架构,主要应用于局域网内.在这之前经历了集中计算模式,随着计算机网络的进步与发展,尤其是可视化工具的应用,出现过两层C/S和三层C/S架 ...

  7. python提供什么机制处理程序运行错误_浅谈Python异常处理机制

    异常机制己经成为衡量一门编程语言是否成熟的标准之一,使用异常处理机制的 Python 程序有更好的容错性,更加健壮. 对于计算机程序而言,情况就更复杂了一一没有人能保证自己写的程序永远不会出辛苦!就算 ...

  8. 【如何学习网安(浅谈)】

    相信各位小伙伴一定听所过各种黑客的流弊操作,键盘声满天飞.呵呵,在下也曾幻想过有朝一日能够向当初中国红客一样,攻陷漂亮国的白宫网站.将台湾是中国的一部分几个大字狠狠的挂在上面.然而在下不才,还需经过不 ...

  9. 大学生使用计算机遇到的问题,大学生计算机学习遇到的问题浅谈

    前言:计算机系统主要包含硬件和软件两类结构单元,而随着集成电路的整改,涉及整个计算机软硬件资源的升级进度也开始骤然加快,其间出现更加多元化的应用程序,进一步人性化地满足民众生活娱乐和日常学习工作等要求 ...

  10. UGUI深度学习(二)-- 浅谈特效穿层问题

    一个老生常谈的问题,只不过之前一直没有自己处理过,正好有机会自己去研究了一下. 问题:particle在UI面板中的渲染顺序问题.由于UI渲染和Particle渲染是分为2个大组进行分别渲染,所以会出 ...

最新文章

  1. 页面自动获取焦点影响页面切换效果_ReactIndex - 让文件夹index页面变得更有实用性 (替换传统Web服务器index页)...
  2. python画三维平面-Python三维绘图--Matplotlib
  3. linux解压后缀为.xz,xz后缀名文件解压方法
  4. 深入了解Java 8中的可选类API
  5. PWN-PRACTICE-BUUCTF-9
  6. window下远程监控linux下tomcat的jvm
  7. SP2916 GSS5 - Can you answer these queries V
  8. 赞!史上最强音视频下载神器youtube-dl回归,GitHub75k星
  9. django如何连接mysql_Django如何连接mysql
  10. IIS发布网站遇到的异常
  11. 仙人掌(cactus)
  12. 华为鸿蒙系统和奔驰公司,华为已行动,又是一个千亿BG,奔驰已经加入
  13. java计算机毕业设计飞机航班信息查询系统演示视频2021MyBatis+系统+LW文档+源码+调试部署
  14. audio接线图解_图文:主板跳线(排线)连接技巧HD AUDIO连线接法
  15. 99%的程序员都不明白:弱者和强者的唯一区别
  16. 网络字节序与主机字节序的转换 - HEN_MAN的专栏 - 博客频道 - CSDN.NET
  17. java爬虫实战(3):网易云音乐评论,歌曲,歌单,歌词下载
  18. 什么是MES生产管理和生产制造执行系统?有哪些系统模块组成?
  19. java 读取pdf签名域_Java 获取PDF中的数字签名信息
  20. linux服务器远程修改mac地址,linux下修改MAC地址问题解决方法

热门文章

  1. setValuesForKeysWithDictionary崩溃
  2. 三星android5.0基带,三星手机刷入基带详细图文操作教程
  3. [英文话剧][搞笑话剧短剧][中英文对照]7人话剧 新三顾茅庐
  4. openmv图像格式不支持问题解决方案
  5. 科技 计算机 事迹 大学,计算机学院
  6. 读LockSupport源码
  7. Activiti学习之根据条件判断流程走向
  8. 庄懂着色器_L13_特效篇
  9. 小狮子荣光不复 瑞星信息去年亏损7300万元
  10. Genlovy_Hoo大神的杰作