GoLang之错误处理
错误处理
error
Go语言引入了一个错误处理的标准模式,即error接口,该接口定义如下:
type error interface {
    Error() string
}
对于大多数函数,如果要返回错误,可以将error作为多返回值的最后一个:
func foo(param int)(ret int, err error)
{
...
}
调用时的代码:
n, err := foo(0)
if err != nil {
// 错误处理
} else {
// 使用返回值n
}
我们还可以自定义错误类型,一个例子:
package main import "fmt"
import "errors" //自定义的出错结构
type myError struct {
arg int
errMsg string
}
//实现Error接口
func (e *myError) Error() string {
return fmt.Sprintf("%d - %s", e.arg, e.errMsg)
} //两种出错
func error_test(arg int) (int, error) {
if arg < 0 {
return -1, errors.New("Bad Arguments - negtive!")
}else if arg >256 {
return -1, &myError{arg, "Bad Arguments - too large!"}
}
return arg*arg, nil
} //相关的测试
func main() {
for _, i := range []int{-1, 4, 1000} {
if r, e := error_test(i); e != nil {
fmt.Println("failed:", e)
} else {
fmt.Println("success:", r)
}
}
}
defer
你可以在Go函数中添加多个defer语句,当函数执行到最后时,这些defer语句会按照逆序执行(即最后一个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)
}
如果defer后面一条语句干不完清理工作,也可以使用一个匿名函数:
defer func(){
    ...
}()
注意,defer语句是在return之后执行的,例如:
func test() (result int) {
    defer func() {
        result = 12
    }()
    return 10
}
func main() {
    fmt.Println(test())     // 12
}
panic() recover()
panic()函数用于抛出异常,recover()函数用于捕获异常,这两个函数的原型如下:
func panic(interface{})
func recover() interface{}
当在一个函数中调用panic()时,正常的函数执行流程将立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐层向上执行panic()流程,直至所属的goroutine中所有正在执行的函数被终止。错误信息将被报告,包括在调用panic()函数时传入的参数,这个过程称为错误流程处理。
panic()接受一个interface{}参数,可支持任意类型,例如:
panic(404)
panic("network broken")
panic(Error("file not exists"))
在defer语句中,可以使用recover()终止错误处理流程,这样可以避免异常向上传递,但要注意recover()之后,程序不会再回到panic()那里,函数仍在defer之后返回。
func foo() {
    panic(errors.New("i'm a bug"))
    return
}
func test() (result int) {
    defer func() {
        if r := recover(); r != nil {
            err := r.(error)
            fmt.Println("Cache Exception:", err)
        }
    }()
    foo()
    return 10
}
func main() {
    fmt.Println(test())     // 0
}
注意,在一个函数中panic被调用后,其defer语句仍会执行,
func foo()(n int) {
    defer func() {
        if r := recover(); r != nil {
            n++    // take effective
        }
    }()
    n++             // take effective
    panic(errors.New("i'm a bug"))
    n++             // take no effective
    return n
}
GoLang之错误处理的更多相关文章
- 个人犯的一个golang routine错误
		这个其实不是错误,2个写法没有区别.-2015.11.22 认识golang也不少时间了,也做过几个项目.最近发现之前用golang写的一个服务,内存涨得比较快,一直没找出来原因来.今天把疑惑发到群里 ... 
- [golang note] 错误处理
		错误处理 • 错误处理的标准模式 √ golang错误处理的标准模式:error接口. √ golang函数如果要返回错误,规范上是将error作为多返回值中的最后一个,但这并非是强制要求. ▶ er ... 
- [Golang]-4 错误处理、Panic、Defer
		目录 错误和异常 案例 Panic Defer 使用 defer+recover 来处理错误 参考文章: Go 语言使用一个独立的·明确的返回值来传递错误信息的.这与使用异常的 Java 和 Ruby ... 
- golang处理错误的艺术
		golang中关键API的调用都会在最后返回err(golang多值返回). 调用者可以选择处理, 或者不处理该err, 或原装返回给上一层的调用者. golang中的err是error类型, typ ... 
- Go_19: Golang 中错误与异常需要重新认识
		如何进行错误处理,这是一个Go程序员之间,特别是一些新的Go程序员,会经常讨论的问题.讨论到最后往往由于以下代码的多次出现而变成了抱怨. if err != nil { return err } 我们 ... 
- Golang 中错误与异常需要重新认识
		如何进行错误处理,这是一个Go程序员之间,特别是一些新的Go程序员,会经常讨论的问题.讨论到最后往往由于以下代码的多次出现而变成了抱怨. if err != nil { return err } 我们 ... 
- golang error错误处理
		error定义 数据结构 go语言error是一普通的值,实现方式为简单一个接口. // The error built-in interface type is the conventional i ... 
- 『GoLang』错误处理
		Go 没有像 Java 和 .NET 那样的 try/catch 异常机制:不能执行抛异常操作.但是有一套 defer-panic-and-recover 机制. Go 的设计者觉得 try/catc ... 
- golang常见错误
		import import unuse package: error : imported and not used: "os" := = c := 1 // error non- ... 
随机推荐
- eclipse 导入android 项目重名解决方法
			在进行andoid 开发时会用到许多的开源框架,但有时候发现几天框架的项目名字都是 library. 解决方法: 1.如果项目中没有 .project 文件,直接修改项目文件夹的名字即可,注意在你引用 ... 
- Android笔记--LinearLayout
			LinearLayout 即线性布局,让子元素水平或垂直的排列在 layout中,子元素不会换行,当排到末尾时,剩下的组件将不会被显示出来. LinearLayout 常用的属性及方法: XML属性 ... 
- Redis设计与实现:读书笔记之一
			第一部分:数据结构与对象 Redis支持的数据类型 字符串对象 列表对象 Hash对象 集合对象 有序集合对象 2.数据结构 Redis的所有数据类型都是: key-value pair 对象 Red ... 
- css3中linear-gradient()的使用
			用线性渐变创建图像. 如果想创建以对角线方式渐变的图像,可以使用 to top left 这样的多关键字方式来实现. 示例代码: linear-gradient(#fff, #333); linear ... 
- 【枚举】Consonant Fencity @upcexam5110
			时间限制: 3 Sec 内存限制: 512 MB 题目描述 There are two kinds of sounds in spoken languages: vowels and consonan ... 
- 【组合数】微信群 @upcexam6016
			时间限制: 1 Sec 内存限制: 128 MB 题目描述 众所周知,一个有着6个人的宿舍可以有7个微信群(^_^,别问我我也不知道为什么),然而事实上这个数字可以更大,因为每3个或者是更多的人都可以 ... 
- Office Web Apps 2013 修改Excel在线查看文件大小限制
			前言 最近搭建了一个OWA 2013环境,帮客户实现在线查看Excel文档,不过,使用过程中出现了错误,文件大小超过10MB就无法预览了,查了好久,发现需要使用PowerShell命令进行修改. 1. ... 
- springboot获取properties文件的配置内容(转载)
			1.使用@Value注解读取读取properties配置文件时,默认读取的是application.properties. application.properties: demo.name=Name ... 
- [Web 前端]   我不再使用React.setState的3个原因
			copy from : https://blog.csdn.net/smk108/article/details/85237838 从几个月前开始,我在新开发的React组件中不再使用setState ... 
- TCP 粘包问题浅析及其解决方案
			最近一直在做中间件相关的东西,所以接触到的各种协议比较多,总的来说有TCP,UDP,HTTP等各种网络传输协议,因此楼主想先从协议最基本的TCP粘包问题搞起,把计算机网络这部分基础夯实一下. TCP协 ... 
