Go语言的错误异常处理机制及其应用
一、背景
在日常编写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
相关文章:

【Win10 应用开发】语音命令与App Service集成
昨天,老周演示了语音命令集成这一高大上功能,今天咱们来点更高级的语音命令。 在昨天的例子中,响应语音命令是需要启动应用程序的,那么如果可以不启动应用程序,就直接在小娜面板上进行交互,是不是会更高大小…

Maya 2022中的硬表面建模技术学习视频教程
Maya 2022中的硬表面建模 信息: 使用正确的拓扑和边流在Maya中建模硬曲面对象。 你会学到什么 硬质表面工具和技术 细分工作流程 边缘流动控制 正确拓扑 材料设置 Studio Lightning 渲染 持续时间16小时30分钟 1280X720 MP4 大小解压后:11.5G 语言:英…

六年级小学python第四讲_python第四讲
列表的排序 升序:从小到大的排序 降序:从大到小的排序 示例: num_list [120,250,11,44,77,45,22,390] num_list.sort() # 升序 - 从小到大 print(num_list) # 对列表本身做了修改 num_list.sort(reverseTrue)#降序 为False#升序 print(num_list) 反转 p…

android之AlertDialog 点击其它区域自己主动消失
遇到一个问题记录下来,在开发中使用了AlertDialog,想点击屏幕其它区域的时候让这个dialog消失,一開始不做不论什么设置,在小米手机能够正常显示,可是在三星中却有问题。后来发现少了一个属性: View dilaogV…

中级实训第一天的自学报告
目录【阅读时间:约10分钟】中级实训第一天的自学报告姓名:隐藏敏感信息 学号:隐藏敏感信息一、Vi/Vim二、Java三、Ant四、Junit【附加】五、SonarQube【附加】六、 编译运行BugRunner七、 总结中级实训第一天的自学报告 姓名:隐藏…

完整的Blender三维课程:素描到三维艺术的初学者
使用Blender创建3D艺术。初级课程 你会学到什么 使用Blender并理解它的界面 创建3D模型 创建您自己的材料 布料仿真、纹理和雕刻 第三种解释的相机法则 照相机景深 灯光设置 渲染 如何使用参考素材进行3D素描和建模?参考镜头也包括在内。 课程中包含所有章节场景文…

VirtualBox: Effective UID is not root
为什么80%的码农都做不了架构师?>>> 桌面上运行virtualbox出错: The virtual machine xp has terminated unexpectedly during startup with exit code 1 (0x1). Effective UID is not root(euid1000 egid482 uid1000 gid482)(rc-10) Please try reinst…

ironpython 教程_「ironpython」VS2017 IronPython做界面
本人开始做毕设了,但老师说工具要有界面,所以就开始找Python做界面的东西……之前做过C#的界面,脱拉拽很快界面就完成了,后来我查了下IronPython是用C#写的python解释器,也可以脱拉拽做界面,于是就开始尝试…

4、jQuery实现的全选、反选和不选功能
2019独角兽企业重金招聘Python工程师标准>>> 这个地址更权威:最好的选择:http://www.sucaihuo.com/js/10.html <html><head><title>TODO supply a title</title><meta charset"UTF-8"><meta name…

构建自己的PHP框架--构建缓存组件(1)
作为一个框架,我们还没有相应的缓存组件,下面我们就来构建我们的缓存组件。 先来定义一下接口,在 src 文件夹下创建 cache 文件夹,在cache文件夹下创建 CacheInterface.php 文件,其中定义 Cache 相应的接口,…

基于Golang的CLI 命令行程序开发
基于Golang的CLI 命令行程序开发 【阅读时间:约15分钟】一. CLI 命令行程序概述二. 系统环境&项目介绍&开发准备1.系统环境2.项目介绍3.开发准备三.具体程序设计及Golang代码实现1.selpg的程序结构2.导入的库3.sp_args结构体4.全局变量4.main函数5.process_…

Photoshop创造氛围照片合成视频教程含素材
数百个高分辨率工具和9个完整项目! 这个包包含开始创建史诗大气合成所需的一切-超过四个小时的基于项目的深入教程和超过400个合成工具。 大小解压后:10.7G 含课程素材文件 1920X1080 mp4 语言:英语中英文字幕(根据原英文字幕机…

java c++的区别_Java语言与C、C++之间的区别?
小伙伴你知道吗?Java是由C开发而来的,并且在当时一直被搁置。随着Java语言的崛起那么Java和C/C有什么不同和相同之处呢?通过上述我们知道那Java前身是C,并且保留了C的大部分内容,其编程方式也类似于C。但Java的句法更清…

Android编程获取网络连接状态及调用网络配置界面
获取网络连接状态 随着3G和Wifi的推广,越来越多的Android应用程序需要调用网络资源,检测网络连接状态也就成为网络应用程序所必备的功能。 Android平台提供了ConnectivityManager 类,用于网络连接状态的检测。 Android开发文档这样描述Connec…

学习在Unity中创建一个动作RPG游戏
游戏开发变得简单。使用Unity学习C#并创建您自己的动作角色扮演游戏! 你会学到什么 学习C#,一种现代通用的编程语言。 了解Unity中2D发展的能力。 发展强大的和可移植的解决问题的技能。 了解游戏开发流程。 了解面向对象编程在实践中是如何工作的。 Le…

python数组对应元素相乘_python的几种矩阵相乘的公式详解
1. 同线性代数中矩阵乘法的定义: np.dot() np.dot(A, B):对于二维矩阵,计算真正意义上的矩阵乘积,同线性代数中矩阵乘法的定义。对于一维矩阵,计算两者的内积。见如下Python代码: import numpy as np # 2-D…

c#属性中的get和set属性
get是给属性赋值,set是取属性的值。 get、set用法: 一是隐藏组件或类内部的真是成员; 二是用来建立约束的,比如,实现“有我没你”这种约束; 三是用来响应属性变化事件,当属性变化是做某事&#…

基于Golang的监听读取配置文件的程序包开发——simpleConfig_v1
基于Golang的监听&读取配置文件的程序包开发——simpleConfig_v1 【阅读时间:约10分钟】 一、配置文件概述二、系统环境&项目介绍1.系统环境2.项目的任务要求三、具体程序设计及Golang代码实现1. 数据结构2. init函数模块3.listen函数模块4.watch函数模块四…

如何在Mac环境下搭建svn服务器端环境
为什么80%的码农都做不了架构师?>>> 在Windows环境中,我们一般使用TortoiseSVN来搭建svn环境。在Mac环境下,由于Mac自带了svn的服务器端和客户端功能,所以我们可以在不装任何第三方软件的前提下使用svn功能࿰…

kitbash贫民区三维场景模型 Kitbash3d – Favelas
参观临时城市中心 想象一下新兴的后世界末日城市中心,这里有大量的临时住所、建筑群、小屋、道具和固定装置。用一系列非常详细的废弃街区快速构建您的场景,并用波纹铁、水箱、折叠椅和劣质电线进一步修饰它们。从足球场到摇摇欲坠的码头,每一…

python编程代码示例_python编程线性回归代码示例
用python进行线性回归分析非常方便,有现成的库可以使用比如:numpy.linalog.lstsq例子、scipy.stats.linregress例子、pandas.ols例子等。 不过本文使用sklearn库的linear_model.LinearRegression,支持任意维度,非常好用。 一、二维…

单例模式的两种实现方式对比:DCL (double check idiom)双重检查 和 lazy initialization holder class(静态内部类)...
首先这两种方式都是延迟初始化机制,就是当要用到的时候再去初始化。 但是Effective Java书中说过:除非绝对必要,否则就不要这么做。 1. DCL (double checked locking)双重检查: 如果出于性能的考虑而需要对实例域(注意…

【golang程序包推荐分享】go-ini、viper、godoc
【golang程序包推荐&分享】go-ini、viper、godoc一、go-ini1.程序包简介2.下载安装3.简单使用【截取自官网】二、viper1.程序包简介2.下载安装3.简单使用三、godoc1.程序包简介2.下载安装3.简单使用一、go-ini 1.程序包简介 ini 是常用的配置文件格式,而go-in…

Request To JavaBean(请求对象转换为JavaBean对象)
背景: 经常要从request等对象取出值来赋入bean中,如果不用MVC框架的绑定功能的话,麻烦 一 参考资料 1 http://jc-dreaming.iteye.com/blog/563893 2 http://www.iteye.com/topic/76043 3 http://xubindehao.iteye.com/blog/754807 4 http://javafenger.iteye.com/b…

在Substance Designer中创建砖墙视频教程
学习在Substance Designer中创建复杂材料的高级技术。 如果你想进入游戏行业,想学习如何创建高质量的纹理和学习物质设计,那么这个课程是给你的。 我设计了这个课程,从一开始就带你,教你我用来创建AAA纹理的3个步骤:图案ÿ…

python requests 动态加载_python requests 高级用法
HTTP动词 Requests 提供了几乎所有HTTP动词的功能:GET、OPTIONS、HEAD、POST、PUT、PATCH、DELETE。以下内容为使用 Requests 中的这些动词以及 Github API 提供了详细示例。 我将从最常使用的动词 GET 开始。HTTP GET 是一个幂等方法,从给定的 URL 返回…

redis配置开机启动
2019独角兽企业重金招聘Python工程师标准>>> 一、下载安装 去http://download.redis.io/releases/现在最新的redis版本解压 tar zxvf xxx.tar.gz编译进入到解压开的目录,执行:make && make install(可选)添加到bin目录cp redis-serve…

Docker exec命令详细使用指南
Docker exec命令是Docker提供的一个强大工具,用于在正在运行的容器中执行命令。本文将详细介绍Docker exec命令的用法和示例,帮助大家更好地理解和使用这个命令。Docker是一种流行的容器化平台,允许我们在容器中运行应用程序。有时候,在容器内执行命令可以帮助我们调试、排查问题或进行其他操作。这就是Docker exec命令发挥作用的时候。本文详细介绍了Docker exec命令的用法和示例。

Docker网络详解
如何自定义一个网络?查看新创键的mynet详细信息:# 创建两个使用相同自定义网络的容器# 测试容器互连^C^C。

Django Python:完整的BUNDLE + Django真实项目2021
Django和python Bundle:从学习python的所有基础知识到高级python再到UI设计TKINTER,然后是Django 你会学到: 学习编程的基础知识 学习Python编程语言 学习Django & Bootstrap框架 为真实世界的Python程序编写代码 用Python创建一个真实世界的网站 学习使用TKIn…