golang错误处理
1. 错误
错误用内建的error类型来表示。
type error interface {
Error() string
}
error 有了一个签名为 Error() string 的方法。所有实现该接口的类型都可以当作一个错误类型。Error()方法给出了错误的描述。
package main
import (
"fmt"
"os"
) func main(){
f, err := os.Open("/test.txt")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(f.Name(), "opened successfully")
}
output:
open /test.txt: no such file or directory
fmt.Println 在打印错误时,会在内部调用 Error() string 方法来得到该错误的描述。
虽然获取了发生错误的文件路径,但是这种方法很不优雅。随着语言版本的更新,这条错误的描述随时都有可能变化,使我们程序出错。
1) 断言底层结构体类型,使用结构体字段获取更多信息
通过阅读Open函数文档可知,返回的错误类型是*PathError。
type PathError struct {
Op string
Path string
Err error
}
func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
可通过断言*PathError类型,获取结构体详细字段内容:
err是接口变量,err(*os.PathError)断言err的类型*os.PathError,从而获取接口的底层值,即*PathError。
f, err := os.Open("/test.txt")
if err, ok := err.(*os.PathError); ok {
fmt.Println("File at path", err.Path, "failed to open")
return
}
2)断言底层结构体类型,调用结构体方法获取更多信息
3)直接比较
filepath 包中的 ErrBadPattern 定义如下:
var ErrBadPattern = errors.New("syntax error in pattern")
直接比较错误类型
files, error := filepath.Glob("[")
if error != nil && error == filepath.ErrBadPattern {
fmt.Println(error)
return
}
2.自定义错误
创建自定义错误最简单的方法是使用 errors 包中的 New 函数。
package errors // New returns an error that formats as the given text.
func New(text string) error {
return &errorString{text}
} // errorString is a trivial implementation of error.
type errorString struct {
s string
} func (e *errorString) Error() string {
return e.s
}
在函数中应用errors.New():
func circleArea(radius float64) (float64, error) {
if radius < {
return , errors.New("Area calculation failed, radius is less than zero")
}
return math.Pi * radius * radius, nil
}
fmt.Errorf()打印错误信息
if radius < {
return , fmt.Errorf("Area calculation failed, radius %0.2f is less than zero", radius)
}
使用结构体类型和字段提供错误的更多信息
使用指针接收者 *areaError,实现了 error 接口的 Error() string 方法。
type areaError struct {
err string
radius float64
}
func (e *areaError) Error() string {
return fmt.Sprintf("radius %0.2f: %s", e.radius, e.err)
}
if radius < {
return , &areaError{"radius is negative", radius}
}
使用结构体类型的方法来提供错误的更多信息
type areaError struct {
err string //error description
length float64 //length which caused the error
width float64 //width which caused the error
}
func (e *areaError) Error() string {
return e.err
}
func (e *areaError) lengthNegative() bool {
return e.length <
}
func (e *areaError) widthNegative() bool {
return e.width <
}
func rectArea(length, width float64) (float64, error) {
err := ""
if length < {
err += "length is less than zero"
}
if width < {
if err == "" {
err = "width is less than zero"
} else {
err += ", width is less than zero"
}
}
if err != "" {
return , &areaError{err, length, width}
}
return length * width, nil
}
3.panic
当函数发生 panic 时,它会终止运行,在执行完所有的延迟函数后,程序控制返回到该函数的调用方。这样的过程会一直持续下去,直到当前协程的所有函数都返回退出,然后程序会打印出 panic 信息,接着打印出堆栈跟踪(Stack Trace),最后程序终止。
需要注意的是,你应该尽可能地使用错误,而不是使用 panic 和 recover。只有当程序不能继续运行的时候,才应该使用 panic 和 recover 机制。
panic 有两个合理的用例。
- l 发生了一个不能恢复的错误,此时程序不能继续运行。 一个例子就是 web 服务器无法绑定所要求的端口。在这种情况下,就应该使用 panic,因为如果不能绑定端口,啥也做不了。
- l 发生了一个编程上的错误。 假如我们有一个接收指针参数的方法,而其他人使用 nil 作为参数调用了它。在这种情况下,我们可以使用 panic,因为这是一个编程错误:用 nil 参数调用了一个只能接收合法指针的方法。
func panic(interface{})
panic(errors.New("error is ..."))
recover 是一个内建函数,用于重新获得 panic 协程的控制。
func recover() interface{}
recover()返回的是panic()传入的interface,一般为error。
只有在延迟函数的内部,调用 recover 才有用。在延迟函数内调用 recover,可以取到 panic 的错误信息,并且停止 panic 续发事件(Panicking Sequence),程序运行恢复正常。如果在延迟函数的外部调用 recover,就不能停止 panic 续发事件。
只有在相同的 Go 协程中调用 recover 才管用。recover 不能恢复一个不同协程的 panic。
参考:Go 系列教程 —— 32. panic 和 recover
golang错误处理的更多相关文章
- Golang错误和异常处理的正确姿势
Golang错误和异常处理的正确姿势 错误和异常是两个不同的概念,非常容易混淆.很多程序员习惯将一切非正常情况都看做错误,而不区分错误和异常,即使程序中可能有异常抛出,也将异常及时捕获并转换成错误.从 ...
- 【GoLang】GoLang 错误处理 -- 使用异常的思路进行处理
go处理错误的另一种方式 go处理错误常见的方式是 err := funcReturningError() if err != nil { // 处理错误 } 然而因为过于繁琐而饱受诟病.下文简述另一 ...
- GOLANG错误处理最佳方案errors wrap, Defer, Panic, and Recover
Simple error handling primitives: https://github.com/pkg/errors Defer, Panic, and Recover: ...
- golang 错误处理与异常
原文地址 golang 中的错误处理的哲学和 C 语言一样,函数通过返回错误类型(error)或者 bool 类型(不需要区分多种错误状态时)表明函数的执行结果,调用检查返回的错误类型值是否是 nil ...
- 【GoLang】GoLang 错误处理 -- 异常处理思路示例
代码: package main import ( "fmt" // "testing" ) var Pkg = "packageName" ...
- 【GoLang】GoLang 错误处理 -- 官方推荐方式 示例
最严谨的方式,Always检查error,并做相应的处理 项目结构: 代码: common.go: package common import ( "github.com/pkg/error ...
- 【GoLang】GoLang 错误处理 -- 使用 error is value 的思路处理,检查并处理error
吐血推荐: https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully 参考资料: https:/ ...
- Golang错误处理函数defer、panic、recover、errors.New介绍
在默认情况下,当发生错误(panic)后,程序就会终止运行 如果发生错误后,可以捕获错误,并通知管理人员(邮件或者短信),程序还可以继续运行,这当然无可厚非 errors.New("错误信息 ...
- golang错误处理机制:panic与recover
原文地址:http://www.niu12.com/article/14 panic知识点 package main import ( "fmt" "github.com ...
随机推荐
- echo的色彩处理
在Shell脚本中,可以使用echo的-e选项使显示内容呈现出不同的颜色. 格式1:echo -e "\033[背景颜色代码;文字颜色代码m 输出的字符串 \033[0m" 格式2 ...
- PMP 第5章错题总结
1.工作分解结构是项目团队与相关方之间沟通的有效工具之一2.控制账户是工作分解结构某个层次上的要素,以便与工作包一一对应3.项目范围说明书包括产品范围.产品验收标准.项目可交付成果.项目除外责任,以及 ...
- Python - Django - form 组件动态从数据库取 choices 数据
app01/models.py: from django.db import models class UserInfo(models.Model): username = models.CharFi ...
- SonarQube + Jenkins代码审查环境安装文档 v1.2
1. 安装SonarQube 1.1. 下载 下载地址:https://www.sonarqube.org/downloads/ 本次使用安装包为:sonarqube-7.4.zip 需要提前准备jd ...
- jquery对div元素进行鼠标移动(稍稍修改下可以实现div跟随鼠标)
/* 网上找了资料都是对于event.clientX和offset().left进行了计算,但是去掉了这个计算方式,直接使用当前坐标也一样,效果都一样不太好 strHeader:标题 jquery定位 ...
- [转帖]LINUX PID 1 和 SYSTEMD
LINUX PID 1 和 SYSTEMD 2017年07月16日 陈皓 评论 46 条评论 57,176 人阅读 https://coolshell.cn/articles/17998.html ...
- 抽象工厂(AbstractFactory)模式
抽象工厂模式又称工具箱模式.其实抽象工厂模式可以简单的理解为一个工厂生成一个产品族的产品. 抽象工厂模式可以向客户端提供一个接口,使得客户端在不指定产品的具体类型的情况下,创建多个产品族中的产品对象. ...
- 简单工厂(SimpleFactory)模式
简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例. 简单工厂就是将多个if,else...代码 ...
- Git GUI,Git Bash,Git CMD之间的区别
Git GUI,Git Bash,Git CMD之间的区别 Git Bash: Bash,Unix shell的一种,Linux与Mac OS X v10.4都将它作为默认shell.Git Bash ...
- spring框架是怎么样通过properties来获得对象的?
首先我们要知道java获得对象的方式有四种: 1.通过new语句实例化一个对象. 2.通过反射机制创建对象. 3.通过clone()方法创建对象 3.通过反序列化的方式创建对象 在spring框架中, ...