1,error接口

Go语言引入了一个关于错误处理的标准模式,即error接口,它是Go语言内建的接口类型,该接口的定义如下:

type error interface {
Error() string
}

Go语言的标准库代码包errors为用户提供如下方法:

package errors

type errorString struct {
text string
} func New(text string) error {
return &errorString{text}
} func (e *errorString) Error() string {
return e.text
}

另一个可以生成error类型值的方法是调用fmt包中的Errorf函数:

package fmt
import "errors" func Errorf(format string, args ...interface{}) error {
return errors.New(Sprintf(format, args...))
}

示例代码

import (
"errors"
"fmt"
) func main() {
var err1 error = errors.New("a normal err1")
fmt.Println(err1) //a normal err1 var err2 error = fmt.Errorf("%s", "a normal err2")
fmt.Println(err2) //a normal err2
}

函数通常在最后的返回值中返回错误信息:

import (
"errors"
"fmt"
) func Divide(a, b float64) (result float64, err error) {
if b == {
result = 0.0
err = errors.New("runtime error: divide by zero")
return
} result = a / b
err = nil
return
} func main() {
r, err := Divide(10.0, )
if err != nil {
fmt.Println(err) //错误处理 runtime error: divide by zero
} else {
fmt.Println(r) // 使用返回值
}
}

2, panic

  在通常情况下,向程序使用方报告错误状态的方式可以是返回一个额外的error类型值。

  但是,当遇到不可恢复的错误状态的时候,如数组访问越界、空指针引用等,这些运行时错误会引起painc异常。这时,上述错误处理方式显然就不适合了。反过来讲,在一般情况下,我们不应通过调用panic函数来报告普通的错误,而应该只把它作为报告致命错误的一种方式。当某些不应该发生的场景发生时,我们就应该调用panic。

  一般而言,当panic异常发生时,程序会中断运行,并立即执行在该goroutine(可以先理解成线程,在中被延迟的函数(defer 机制)。随后,程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。

  不是所有的panic异常都来自运行时,直接调用内置的panic函数也会引发panic异常;panic函数接受任何值作为参数。

func panic(v interface{})

调用panic函数引发的panic异常:

func TestA() {
fmt.Println("func TestA()")
} func TestB() {
panic("func TestB(): panic")
} func TestC() {
fmt.Println("func TestC()")
} func main() {
TestA()
TestB()//TestB()发生异常,中断程序
TestC()
}

内置的panic函数引发的panic异常:

func TestA() {
fmt.Println("func TestA()")
} func TestB(x int) {
var a []int
a[x] = //x值为11时,数组越界
} func TestC() {
fmt.Println("func TestC()")
} func main() {
TestA()
TestB()//TestB()发生异常,中断程序
TestC()
}

3,recover

  运行时panic异常一旦被引发就会导致程序崩溃。这当然不是我们愿意看到的,因为谁也不能保证程序不会发生任何运行时错误。

  不过,Go语言为我们提供了专用于“拦截”运行时panic的内建函数——recover。它可以是当前的程序从运行时panic的状态中恢复并重新获得流程控制权。

func recover() interface{}

注意:recover只有在defer调用的函数中有效。

如果调用了内置函数recover,并且定义该defer语句的函数发生了panic异常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运行,但能正常返回。在未发生panic时调用recover,recover会返回nil。

示例代码:

func TestA() {
fmt.Println("func TestA()")
} func TestB() (err error) {
defer func() { //在发生异常时,设置恢复
if x := recover(); x != nil {
//panic value被附加到错误信息中;
//并用err变量接收错误信息,返回给调用者。
err = fmt.Errorf("internal error: %v", x)
}
}() panic("func TestB(): panic")
} func TestC() {
fmt.Println("func TestC()")
} func main() {
TestA()
err := TestB()
fmt.Println(err)
TestC() /*
运行结果:
func TestA()
internal error: func TestB(): panic
func TestC()
*/
}

延迟调用中引发的错误,可被后续延迟调用捕获,但仅最后一个错误可被捕获:

func test() {
defer func() {
fmt.Println(recover())
}() defer func() {
panic("defer panic")
}() panic("test panic")
} func main() {
test()
//运行结果:defer panic
}

go语言入门(8)异常处理的更多相关文章

  1. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  2. GO 语言入门(一)

    GO 语言入门(一) 本文写于 2020 年 1 月 18 日 Go 由 Google 工程师 Robert Griesemer,Rob Pike 和 Ken Thompson 设计的一门编程语言,第 ...

  3. 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)

    1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...

  4. [R]R语言里的异常处理与错误控制

    之前一直只是在写小程序脚本工具,几乎不会对异常和错误进行控制和处理. 随着脚本结构和逻辑更复杂,脚本输出结果的准确性验证困难,同时已发布脚本的维护也变得困难.所以也开始考虑引入异常处理和测试工具的事情 ...

  5. 我为什么反对推荐新人编程C/C++语言入门?

    虽然我接触编程以及计算机时间比较早,但是正式打算转入程序员这个行当差不多是大学第四年的事情 从03年接触计算机,07年开始接触计算机编程, 期间接触过的技术包括 缓冲区溢出(看高手写的shellcod ...

  6. 《C语言入门1.2.3—一个老鸟的C语言学习心得》—清华大学出版社炮制的又一本劣书及伪书

    <C语言入门1.2.3—一个老鸟的C语言学习心得>—清华大学出版社炮制的又一本劣书及伪书 [薛非评] 区区15页,有80多个错误. 最严重的有: 通篇完全是C++代码,根本不是C语言代码. ...

  7. c语言入门教程 / c语言入门经典书籍

    用C语言开始编写代码初级:C语言入门必备(以下两本书任选一本即可) C语言是作为从事实际编程工作的程序员的一种工具而出现的,本阶段的学习最主要的目的就是尽快掌握如何用c语言编写程序的技能.对c语言的数 ...

  8. 【转】c语言入门教程 / c语言入门经典书籍

    用C语言开始编写代码 初级:C语言入门必备 (以下两本书任选一本即可) C语言是作为从事实际编程工作的程序员的一种工具而出现的,本阶段的学习最主要的目的就是尽快掌握如何用c语言编写程序的技能.对c语言 ...

  9. Swift语言入门之旅

    Swift语言入门之旅  学习一门新的计算机语言,传统来说都是从编写一个在屏幕上打印"Hello world"的程序開始的.那在 Swift,我们使用一句话来实现它: printl ...

  10. 【南阳OJ分类之语言入门】80题题目+AC代码汇总

    小技巧:本文之前由csdn自动生成了一个目录,不必下拉一个一个去找,可通过目录标题直接定位. 本文转载自本人的csdn博客,复制过来的,排版就不弄了,欢迎转载. 声明: 题目部分皆为南阳OJ题目. 代 ...

随机推荐

  1. React Native使用code-push实现热更新

    这里就不记录了,下面的传送门介绍的通俗易懂,很详细,一步一步很容易实现成功. http://www.jianshu.com/p/f8689ccf0007

  2. swift 第十二课 as 的使用方法

    忽略的基础性的问题,应该早点写出这个问题的解释比较好,毕竟 swift 好多的地方都用到了 as as!as?,是非常容易搞晕大脑的 1,as使用场合          (1)从派生类转换为基类,向上 ...

  3. github pages + hexo 搭建 blog 遇到的问题

    一. ERROR Deployer not found: git $ hexo d ERROR Deployer not found: git npm install --save hexo-depl ...

  4. The request was rejected because the URL contained a potentially malicious String ";"报错解决

    报错信息 浏览器中看到的报错 错误摘要: The request was rejected because the URL contained a potentially malicious Stri ...

  5. JPG文件结构分析

    [转自网络  作者:一 江秋水] 一.简述 JPEG是一个压缩标准,又可分为标准 JPEG.渐进式JPEG及JPEG2000三种: ①标准JPEG:以24位颜色存储单个光栅图像,是与平台无关的格式,支 ...

  6. 2、PHP变量

    2.1含义与定义形式 就是使用一个“标记符号”(标识符),来代表某个数据. 类比: 用一个名字(姓名),来代表某个人. 用一个身份证号码,来代表某个人... 用一个变量,就可以理解为“使用一个数据”. ...

  7. Charles系列一:Charles功能介绍、下载安装和界面简介

    一:Charles主要功能介绍 Charles是一个HTTP代理/HTTP监视器/反向代理,使开发和测试人员能够查看机器和Internet之间所有的HTTP和SSL/HTTPS流量,这包括请求,响应. ...

  8. Spring mybatis源码篇章-Mybatis的XML文件加载

    通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-Mybatis主文件加载 前话 前文主要讲解了Mybatis的主文件加载方式,本文则分析不使用主文件加载方式 ...

  9. Netty源码剖析-构建链接

    参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! ----主线: 和启动一样也是有两个线程完成的,boss threa ...

  10. thinkphp5中的raw的作用

    模板中输出变量 默认不展示HTMl 使用raw将其中的中的HTMl内容展示出来 <div class="content"> <div class="co ...