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- ...
随机推荐
- ubuntu 配置
这是安装语言包 sudo apt-get install language-pack-touch-zh-hans language-pack-touch-zh-hant 这是安装字体 sudo apt ...
- shell脚本使用技巧5--字符分隔
#!/bin/bash #filename:ifs.sh data="name,sex,rollon,location" oldIFS=$IFS IFS=, for item in ...
- JS Function类型
每个函数都是Function类型的实例,由于函数是对象,函数名实际上是一个指向函数对象的指针,不会与某个函数绑定. 1.函数的声明: (1)函数声明语法: function sum (num1,num ...
- python之封装
封装的主要原因是保护隐私,隔离复杂度 封装分为两个层面: 第一个层面的封装(什么都不用做):创建类和对象会分别创建二者的名称精简,我们只能用类名.或者obj.的方式去访问里面的名字,这本身就是一种分装 ...
- SharePoint 配置PowerShell任务计划
前言 最近,有这么个需求,需要定时为SharePoint更新内容,所以,就想到了PowerShell命令和任务计划(Windows自带的功能,英文叫Task Schedule,在开始菜单里就能找到), ...
- java/javac命令行如何同时引用多个包;错误 TypeError: 'JavaPackage' object is not callable 的含义
出现这类错误提示:'JavaPackage' object is not callable,可以看下所引用的jar包或者class文件是否在java的路径搜索范围内 命令行模式下:javac可以编译* ...
- Swoole PHP windows composer
直接下载了 Swoole PHP 的 Windows 版安装包来用,遇到需要 Composer. 先是下载了 composer.phar.在这里下的 https://getcomposer.org/d ...
- 解决 安装VMwanre tools时 Enter the path to the kernel header files for the 3.10.0-862.14.4.el7.x86_64 kernel
1.使用ctrl+z停止安装vmtools安装 2.然后yum升级kernel-devel yum -y install kernel-devel
- PHP类中self和$this的区别
1.self代表类,$this代表对象2.能用$this的地方一定使用self,能用self的地方不一定能用$this静态的方法中不能使用$this,静态方法给类访问的. 今天在使用静态方法的时候,使 ...
- PHPStrom激活方法
直接用浏览器打开 http://idea.lanyus.com/ 点击页面中的“获得注册码”, 然后在注册时切换至Activation Code选项,输入获得的注册码一长串字符串 如果提示红字体信息, ...