教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Go语言的错误&异常处理机制及其应用

Go语言的错误&异常处理机制及其应用

发布时间:2022-02-02   编辑:jiaochengji.com
教程集为您提供Go语言的错误&异常处理机制及其应用等资源,欢迎您收藏本站,我们将为您提供最新的Go语言的错误&异常处理机制及其应用资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><h1>一、背景</h1>

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

<pre><code class="lang-go hljs">xx<span class="token punctuation">,</span> err <span class="token operator">=</span> <span class="token keyword">func</span><span class="token punctuation">(</span>xx<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token comment">//do sth. to tackle this problem</span> <span class="token punctuation">}</span> </code></pre>

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

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

<h1>
二、golang的错误&异常处理机制</h1> <h2>1.错误与异常的区别</h2> <blockquote>

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

</blockquote>

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

<h2>
2.golang的两种错误处理方式</h2>

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

<h4>
①错误返回</h4>

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

<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span>xx<span class="token punctuation">,</span> err <span class="token builtin">error</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//code</span> <span class="token keyword">return</span> xx<span class="token punctuation">,</span> err <span class="token punctuation">}</span> </code></pre>

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

<pre><code class="lang-go hljs">xx<span class="token punctuation">,</span> err <span class="token operator">=</span> <span class="token keyword">func</span><span class="token punctuation">(</span>xx<span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token comment">//do sth. to tackle this problem</span> <span class="token punctuation">}</span> </code></pre>

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

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

<h4>
②异常捕获</h4>

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

<blockquote>

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

</blockquote>

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

<blockquote>

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

</blockquote>

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

<pre><code class="lang-go hljs"><span class="token keyword">package</span> main <span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"fmt"</span> <span class="token string">"time"</span> <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">//使用defer recover来捕获和处理异常</span> <span class="token keyword">defer</span> <span class="token keyword">func</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> err <span class="token operator">:=</span> <span class="token function">recover</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// recover()是go内置函数,可以捕获到异常</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token comment">//err 不为空</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"err="</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment">//匿名函数</span> num1 <span class="token operator">:=</span> <span class="token number">18342026</span> num2 <span class="token operator">:=</span> <span class="token number">0</span> res <span class="token operator">:=</span> num1<span class="token operator">/</span>num2 <span class="token comment">//异常error</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"res="</span><span class="token punctuation">,</span> res<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"func_test done."</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre>


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

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

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

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

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

<h1>
三、补充</h1> <h2>1.nil的含义</h2>

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

<h2>
2.如何避免“err != nil”的操作</h2>

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

<pre><code class="lang-go hljs">xx<span class="token punctuation">,</span> <span class="token boolean">_</span> <span class="token operator">=</span> <span class="token keyword">func</span><span class="token punctuation">(</span>xx<span class="token punctuation">)</span> </code></pre>

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

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

到此这篇关于“Go语言的错误&异常处理机制及其应用”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Go语言的错误&异常处理机制及其应用
系统化理解PHP中的错误和异常
golang异常机制
go学习(十二)——Go 语言错误与异常处理机制
DataWhale & Golang(十、异常处理)
on error goto与try catch语句介绍
go语言和php的区别是什么?
go 语言学习历程
Go语言学习-错误和异常处理
分析PHP错误处理(核心特性)

[关闭]
~ ~