go语言入门(8)异常处理
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)异常处理的更多相关文章
- 《Ruby语言入门教程v1.0》学习笔记-01
<Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...
- GO 语言入门(一)
GO 语言入门(一) 本文写于 2020 年 1 月 18 日 Go 由 Google 工程师 Robert Griesemer,Rob Pike 和 Ken Thompson 设计的一门编程语言,第 ...
- 踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(1)
1.前言与作者 首先声明,我是由于非常偶然的机会获得<C语言入门很简单>这本书的,绝对不是买的.买这种书实在丢不起那人. 去年这书刚出版时,在CU论坛举行试读推广,我当时随口说了几句(没说 ...
- [R]R语言里的异常处理与错误控制
之前一直只是在写小程序脚本工具,几乎不会对异常和错误进行控制和处理. 随着脚本结构和逻辑更复杂,脚本输出结果的准确性验证困难,同时已发布脚本的维护也变得困难.所以也开始考虑引入异常处理和测试工具的事情 ...
- 我为什么反对推荐新人编程C/C++语言入门?
虽然我接触编程以及计算机时间比较早,但是正式打算转入程序员这个行当差不多是大学第四年的事情 从03年接触计算机,07年开始接触计算机编程, 期间接触过的技术包括 缓冲区溢出(看高手写的shellcod ...
- 《C语言入门1.2.3—一个老鸟的C语言学习心得》—清华大学出版社炮制的又一本劣书及伪书
<C语言入门1.2.3—一个老鸟的C语言学习心得>—清华大学出版社炮制的又一本劣书及伪书 [薛非评] 区区15页,有80多个错误. 最严重的有: 通篇完全是C++代码,根本不是C语言代码. ...
- c语言入门教程 / c语言入门经典书籍
用C语言开始编写代码初级:C语言入门必备(以下两本书任选一本即可) C语言是作为从事实际编程工作的程序员的一种工具而出现的,本阶段的学习最主要的目的就是尽快掌握如何用c语言编写程序的技能.对c语言的数 ...
- 【转】c语言入门教程 / c语言入门经典书籍
用C语言开始编写代码 初级:C语言入门必备 (以下两本书任选一本即可) C语言是作为从事实际编程工作的程序员的一种工具而出现的,本阶段的学习最主要的目的就是尽快掌握如何用c语言编写程序的技能.对c语言 ...
- Swift语言入门之旅
Swift语言入门之旅 学习一门新的计算机语言,传统来说都是从编写一个在屏幕上打印"Hello world"的程序開始的.那在 Swift,我们使用一句话来实现它: printl ...
- 【南阳OJ分类之语言入门】80题题目+AC代码汇总
小技巧:本文之前由csdn自动生成了一个目录,不必下拉一个一个去找,可通过目录标题直接定位. 本文转载自本人的csdn博客,复制过来的,排版就不弄了,欢迎转载. 声明: 题目部分皆为南阳OJ题目. 代 ...
随机推荐
- 绿色版plsql安装和安装包
转: 绿色版plsql安装和安装包 2018年08月07日 19:53:15 YoungLee16 阅读数 4890 最近在使用数据库的时候,或多或少的会出现一些问题,下面总结下如何安装ORACL ...
- 广告行业——数字广告营销中的DSP、SSP、RTB是个什么概念
原文链接1 原文链接2 如我是一个创业公司,没啥钱,老板给了1000块钱预算,让我去投互联网广告,对我说: “小卡啊!给你1000块钱,我知道你没见过那么多的巨款吧!不要被吓着,尽情去挥霍吧!哦对了, ...
- python 时间类型
- jmeter解决乱码
在jmeter.properties 这个文件里面 找到sampleresult.default.encoding=xx 后面xx改成utf-8,然后取消注释 解决jmeterbody里面中文显示不出 ...
- Flutter 拖拽控件Draggable
Flutter提供了强大的拖拽控件,可以灵活定制,并且非常简单.下面作一个拖拽的案例. Draggable Widget Draggable控件负责就是拖拽,父层使用了Draggable,它的子元素就 ...
- OPC Utgard的数据访问方式
1.同步读取某个点位的值 Item项的read()方法 Server server = new Server(BaseConfiguration.getCLSIDConnectionInfomatio ...
- vim实现批量注释和批量删除注释
批量注释 1.进入文档,vim test.txt 后,按住ctrl+v进入VISUAL BLOCK模式,上下选择需要注释的行 2.按大写键,再按i,或者直接按shift+i,进入INSERT模式,输入 ...
- 一步步分析Java深拷贝的两种方式-clone和序列化
今天遇到一道面试题,询问深拷贝的两种方法.主要就是clone方法和序列化方法.今天就来分析一下这两种方式如何实现深拷贝.如果想跳过解析的朋友,直奔"重点来了!"寻找答案. clon ...
- Java编程思想(三)控制程序流程
3.1.10逗号运算符 我们可以使用一系列由逗号分隔的语句,而且哪些语句均会独立执行. 3.1.15复习计算顺序
- [Cometoj#3 B]棋盘_状压dp
棋盘 题目链接:https://cometoj.com/contest/38/problem/B?problem_id=1535 数据范围:略. 题解: 因为行数特别小,所以$dp$的时候可以状压起来 ...