go语言异常处理

error接口

go语言引入了一个关于错误错里的标准模式,即error接口,该接口的定义如下:

type error interface{
Error() string
}

对于要返回错误的大多数函数来说,大致上都可以定义为如下的模式,将error作为多个返回值中的最后一个,但是这并非是强制要求

func Foo(param int) (n int,err error){
//
}

调用该函数的时候建议按照如下的方式处理错误情况

n,err := Foo(0)
if err != nil{
//处理错误
}else{
//处理结果
} 那么,如何自定义error类型呢,我们以Go库中的实际代码为例来说明,首先,定义一个承载错误信息的类型,因为Go中的接口非常的灵活,你根本不需要像别的语言一样使用继承或则implements来明确指定类型和接口之间的关系,代码如下:

type PathError struct{

Op string

Path string

Err error

}

这样定义后,编译器如何知道PathError可以当成一个error来传递呢?关键在于下面的代码实现了Error() 方法:

func (e *PathError) Error() string{
return e.Op + " " + e.Path +" " + e.Err.Error()
} 定义了上述方法之后,就可以直接返回PathError变量了,如下:

func test(name string) (fi FIleInfo,err error){

var stat syscall.Stat_t

err = syscall.Stat(name,&stat)

if err != nil{

return nil,$PathError{"stat",name,err}

}

return file,nil

}

如果在处理错误的时候要获取错误的详细信息,就需要用到类型的转换知识了:

fi,err := os.Stat("a.txt")
if err != nil{
if e,ok := err.(*os.PathError);ok && e.Err != nil{
//获取PathError类型变量e总的其他信息
}
}

defer

关键字defer是Go引入的一个很有意思的特性,他能保证在函数中发生异常的情况下,defer定义的语句仍然会被执行,如下:

func CopyFile(dst,src string) (w int64,err error){
srcFile,err := os.Open(src)
if err != nil{
return
}
defer srcFile.Close()
dstFile,err := os.Create(dst)
if err != nil{
return
}
defer dstFile.Close()
return io.Copy(dstFile,srcFile)
}

即使Copy函数抛出异常,Go仍然会保证文件被正常的关闭,如果据的一句话干不完清理工作的话,可以在defer后加一个匿名函数:

defer func(){
//
}()

值得注意的是一个函数中可以定义多个defer,并且defer语句的顺序是按照先进后出的顺序执行的,也就是说最后一个defer语句将最先被执行

panic()和recover()

GO引入了两个内置的函数panic()和recover()以报告和处理运行时错误和程序中的错误场景

func panic(interface{})
func recover() interface{}

当在一个函数中调用panic函数后,正确的执行流程会被立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐步向上执行panic流程,直到所属的goroutine中所有正在执行的函数被终止,错误信息将被报告,这个过程成为错误处理流程

从panic中传入的interface{}中我们可以看出,该函数接收任意类型的数据

recover用于终止错误处理流程,一般情况下,recover应该在一个使用defer关键字的函数中执行以有效截取错误处理流程,如果在发生异常的goroutine中没有调用recover,会导致该goroutine所属的进程直接退出

下面是一个常用的场景

defer func(){
if r := recover();r!=nil{
log.Printf("Runtime error caught: %v",r)
}
}

go语言异常处理的更多相关文章

  1. 第63课 C语言异常处理

    1. 异常的概念 (1)程序在运行过程中可能产生异常 (2)异常(Exception)与Bug的区别 ①异常是程序运行时可预料的执行分支 ②Bug是程序是的错误,是不被预期的运行方式 2. 异常和Bu ...

  2. Go语言异常处理defer\panic\recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  3. c语言异常处理机制

    异常处理机制:setjmp()函数与longjmp()函数 C标准库提供两个特殊的函数:setjmp() 及 longjmp(),这两个函数是结构化异常的基础,正是利用这两个函数的特性来实现异常. 所 ...

  4. C语言异常处理和连接数据库

    #include <stdio.h> #include <setjmp.h> jmp_buf j; void Exception(void); double diva(doub ...

  5. C语言异常处理之 setjmp()和longjmp()

    异常处理之除0情况 相信大家处理除0时,都会通过函数,然后判断除数是否为0,代码如下所示: double divide(doublea,double b) { const double delta = ...

  6. C语言异常处理编程的三个境界

    http://blog.csdn.net/treefish2012/article/details/17466487 这是上一次看完Herb Sutter的<Exceptional C++> ...

  7. C语言异常处理

    异常的概念-程序在运行过程中可能产生异常-异常(Exception)与Bug的区别 异常是程序运行时可预料的执行分支 Bug是程序中的错误,是不被预期的运行方式 异常(Exception)和Bug的对 ...

  8. GO语言异常处理03---自定义异常

    package main import ( "fmt" "time" ) /* type error interface { Error() string } ...

  9. GO语言异常处理02---返回错误

    package main import ( "errors" "fmt" "math" ) /*计算圆面积,同时返回[结果-错误对]*/ f ...

随机推荐

  1. 一分钟搭建Spring Boot

    1.首先你的电脑需要安装jdk.Apache Maven.Intellij IDEA 2.新建项目  (敲重点,有的同学有没有Spring Initializr 这个请到本文章后面看安装步骤) 3.选 ...

  2. linux目录与文件权限的意义

    现在我们已经知道了Linux系统内文件的三种身份(所有者,用户者,与其他人),知道每种身份都有三种属性(r,w,x),已经能够使用chown,chgrp,chmod去修改这些权限和属性,那么这些文件权 ...

  3. indexOf() 如何判断一个元素在指定数组中是否存在? 找出指定元素出现的所有位置? indexOf()方法 是正序查找,lastIndexOf()是倒叙查找

    indexOf()方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1. let a = [2, 9, 7, 8, 9]; a.indexOf(2); // 0 a.indexOf ...

  4. 接入层高性能缓存技术nginx+redis利器OpenResty

    一. OpenRestyOpenResty是一个基于 Nginx与 Lua的高性能 Web平台,其内部集成了大量精良的 Lua库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极 ...

  5. springboot整合devtool无法热部署

    参见https://www.cnblogs.com/winner-0715/p/6666579.html.

  6. Python设计模式 - UML - 组件图(Component Diagram)

    简介 组件图又称构建图,用于显示系统各组件及各组件关系的物理视图. 组件图通常包括组件.接口.关系.端口和连接器,用来显示程序代码中相应的模块.源文件或源文件集合之间的依赖和泛化关系. 组件图中的组件 ...

  7. 【Unity】打包安卓APK常见问题

    问题:unity error invalid command android 原因:Android版本较新,Unity版本太旧(如4.X),Unity打包APK时调用Android工具使用的命令已被安 ...

  8. POJ 1741 Tree(点分治点对<=k)

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

  9. Android如何在http头信息里设置参数

    在使用http请求server时常常要传递一些参数给server,如IMEI号.平台号.渠道号.客户端的版本号等一些通用信息,像这些参数我们没有必要每次都拼在url后,我们可以统一添加到http头里. ...

  10. jqgrid获取选中行指定列的值

    部分js如下: var id = $("#grid-table").jqGrid('getGridParam','selrow');//根据点击行获得点击行的id(id为jsonR ...