一、背景

在日常编写golang程序或阅读别人的golang代码时,我们总会看到如下的一堆代码块:

xx, err = func(xx)
if err != nil {//do sth. to tackle this problem
}

这种经典的显式错误处理方式,在golang开发中几乎无处不在,了解过golang开发的同学肯定会很熟悉、但同时又可能很痛恨这种麻烦的错误处理方式。

那么golang语言开发者为什么要这样设计呢?nil的意义是什么?它又有什么有趣的应用?对于这些问题,笔记会在下文逐一介绍。

二、golang的错误&异常处理机制

1.错误与异常的区别

错误:意料之内,可能出的问题, 比如网络连接超时,json解析错误等
异常:意料之外,不应该出的问题,比如空指针异常,下标溢出等异常

由上可知,错误与异常的区别,主要在于error是否在预料之内。而能否很好地操控与处理预料之内的error,往往能看出一个程序员水平的高低。

2.golang的两种错误处理方式

golang有两种错误处理方式,分别是错误返回和捕获异常。

①错误返回

golang 使用error接口作为标准错误接口,在标准库函数中,error通常作为函数的最后一个返回值:

func func()(xx, err error){//codereturn xx, err
}

为了处理预料之内的error,golang强制要求程序员处理错误返回,即我们常见的代码片段:

xx, err = func(xx)
if err != nil {//do sth. to tackle this problem
}

当函数执行正确时,返回的err=nil;若err!=nil,程序员需要编写错误提示等。

其中nil的含义及作用可见【三、补充】。

②异常捕获

为了处理预料之外的error,golang使用用到了panic、recover两个内置函数和一个关键字defer来处理异常。

panic——用于抛出异常
recover——捕获异常
defer——声明延迟函数

golang的异常处理/异常捕获过程,可以简单地概括为:

在defer声明的延迟函数中,通过recover捕获panic抛出的异常。
(其中defer要在panic之前进行声明)

例子:使用defer + recover来捕获和处理异常

package mainimport ("fmt""time"
)func test(){//使用defer + recover来捕获和处理异常defer func(){err := recover()  // recover()是go内置函数,可以捕获到异常if err != nil {  //err 不为空fmt.Println("err=", err)}}()//匿名函数num1 := 18342026num2 := 0res := num1/num2 //异常errorfmt.Println("res=", res)
}func main(){test()fmt.Println("func_test done.")
}

3.关于网上对于golang错误处理的吐槽与辩驳

在许多网络论坛中,不少人吐槽golang的“err != nil”的错误处理方式不够优雅,直言在调用各种库函数时都得添加这一代码片段既显得“啰嗦”,又会影响自己的项目开发效率。

然而在笔者看来,这却是一种优秀的安全机制,它强制要求程序员处理有可能产生的error,对于维护项目的安全性与健壮性而言十分重要。

而且,对于熟悉c/c++编程、又觉得java编程比较臃肿的笔者来说,golang的“err != nil”可比java的try catch优雅多了~

此外,对于不喜欢或想要忽略已知的错误时,也有其他的办法避免“err != nil”的操作,具体可见【三、补充】。

三、补充

1.nil的含义

nil和null类似,都是表示空/零。在Go语言中,布尔类型的"0"(初始值)为false,数值类型的"0"为0,字符串类型的"0"为空字符串"",而指针/切片/映射/通道/函数和接口的"0"即为nil。

2.如何避免“err != nil”的操作

虽然预先处理预料之中的错误是一种良好的编程习惯,但有时候因为各种原因也会选择忽略错误(主要是因为懒),而避免“err != nil”的操作笔者目前只用到以下这种方法:

xx, _ = func(xx)

也就是用“_”直接忽略了传送的err参数,但如果有时间还是尽量进行错误处理,毕竟golang如此设计的初衷便是让程序员正视错误,并解决错误。

此外,还有一些有趣的方法可以避免重复的err操作,详情见:如何减少重复err

Go语言的错误异常处理机制及其应用相关推荐

  1. Laravel 5.5 的错误异常处理机制以及应用实例

    一.前言 我们在开发项目中,难免会因为逻辑上的失误而报错,这些报错的展现形式也就是框架封装好的异常处理机制.在项目上线之前,我们还可以根据框架提供的报错信息来锁定错误代码的位置.但是项目上线之后我们是 ...

  2. c语言c2182是什么错误,C语言中一种更优雅的异常处理机制

    上一篇文章对C语言中的goto语句进行了较深入的阐述,实际上goto语句是面向过程与面向结构化程序语言中,进行异常处理编程的最原始的支持形式.后来为了更好地.更方便地支持异常处理编程机制,使得程序员在 ...

  3. 浅谈Go 错误异常处理方式和并发陷进

    任何一门开发语言中,错误和异常处理都是不可回避的问题,Go 中主要通过 error 和 panic 分别表示错误和异常,并提供了较为简洁的错误异常处理机制.作为一门并发性能优越的语言,Go 虽然降低了 ...

  4. recover 没有捕获异常_GO语言异常处理机制panic和recover分析

    本文实例分析了GO语言异常处理机制panic和recover.分享给大家供大家参考.具体如下: Golang 有2个内置的函数 panic() 和 recover(),用以报告和捕获运行时发生的程序错 ...

  5. golang错误处理机制(异常处理)

    看一段代码,引入错误处理 对上面代码的总结: 在默认情况下,当发生错误后(panic) ,程序就会退出(崩溃.) 如果我们希望:当发生错误后,可以捕获到错误,并进行处理,保证程序可以继续执行.还可 以 ...

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

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

  7. C语言异常处理机制——为您的C程序添加异常处理

    C语言异常处理机制--为您的C程序添加异常处理 参考文章: (1)C语言异常处理机制--为您的C程序添加异常处理 (2)https://www.cnblogs.com/jiayu1016/archiv ...

  8. 错误代码0x1 c 语言,Windows程序(API)错误处理机制和错误代码

    一.Windows API错误机制 当我们在自己的代码里调用Windows系统的API函数,系统执行API内部代码,当API内部代码出现错误,会将预先定义好的错误代码写到调用这个API的线程局部存储区 ...

  9. C错误异常处理,异常处理

    预处理器标识#error的目的是什么啊? 指令 用途# 空指令,无任何效果#include 包含一个源代码文件#define 定义宏#undef 取消已定义的宏#if 如果给定条件为真,则编译下面代码 ...

最新文章

  1. 《leetcode》valid-sudoku
  2. itext设置pdf的尺寸_如何获取pdf文档iText 7的页面大小-问答-阿里云开发者社区-阿里云...
  3. 利用FPGA加速实现高性能计算
  4. hdu 5785 Interesting(manacher+前缀和)
  5. 细谈getRequestDispatcher()与sendRedirect()的区别
  6. Mac下编译OpenCV for android
  7. 2010-2020年全国poi兴趣点
  8. 基于Java开发的Java毕业设计实战项目
  9. 文件比较软件修改比较文件时间戳方法
  10. 暴力破解密码 - C++ 递归方法实现
  11. 交通银行一直显示服务器繁忙,交通银行信用卡人工服务一直繁忙
  12. GPS 原始坐标 (WGS-84) ddmm.mmmm 格式转高德(GCJ)百度(BD09)坐标
  13. 理解v8的Isolate调度
  14. 超级简单!编译的C++生成的exe文件发给别人,直接在其他电脑运行超级简单!亲测有效!
  15. 这可能是京东考前焦虑最重的一次618
  16. Python学习笔记(7)——Matplotlib中的Axes.plot(绘制点、线和标记)的用法
  17. 杀人 真心话大冒险 起底
  18. 【NLP】深度文本匹配综述
  19. git pull某单个文件
  20. MobileNet V2 模型分析+解读

热门文章

  1. 恭喜你发现了宝藏,编程习惯-日积月累
  2. Object的finalize()方法的作用是否与C++的析构函数作用相同
  3. Python+OpenCV 图像处理系列(5)—— 图像 ROI 操作及通道的拆分合并
  4. 发送快递:配置静态路由
  5. 一文告诉你Adam、AdamW、Amsgrad区别和联系 重点
  6. 第25章 Pytorch 如何高效使用GPU
  7. Java中如何实现Date与String之间的数据类型转换
  8. LeetCode简单题之两数之和
  9. 左神讲算法——异或的高级操作(两数交换+经典面试题)
  10. CVD-ALD前驱体材料