我的编程空间,编程开发者的网络收藏夹
学习永远不晚

golang中Error如何使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

golang中Error如何使用

golang中Error如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Error是Go语言开发中最基础也是最重要的部分,跟其他语言的try catch的作用基本一致,想想在PHP JAVA开发中,try catch 不会使用,或者使用不灵活,就无法感知到程序运行中出现了什么错误,是特别可怕的一件事。

Error 基础

Golang中 error类型就是一个最基本interface,定义了一个Error()的方法

type error interface {Error() string}

平常使用最多的是这样的

errors.New("error")

在Golang中errors.New这样定义的

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}

其实是返回了一个errorString的结构体,这个结构体实现了Error()方法,所以实现了error interface

看下Error在项目开发中是怎么使用的?

1.定义Error变量

在一段代码里面可能返回了很多个error,我怎么判断这个error是哪一种呢?
是这样的吧

var ERR_MSG = "error"if err.Error() == ERR_MSG

这样的话,多个第三方类库和自己项目的错误描述要是一致的话就无法比较出来了,其实不应该是这样的。
我们看下 beego里面orm是怎么定义的,从上面的基础我们知道errors.New返回的是errorString的指针

var (ErrTxHasBegan    = errors.New("<Ormer.Begin> transaction already begin")ErrTxDone        = errors.New("<Ormer.Commit/Rollback> transaction not begin")ErrMultiRows     = errors.New("<QuerySeter> return multi rows")ErrNoRows        = errors.New("<QuerySeter> no row found")ErrStmtClosed    = errors.New("<QuerySeter> stmt already closed")ErrArgs          = errors.New("<Ormer> args error may be empty")ErrNotImplement  = errors.New("have not implement"))

其实都是使用指针判断的

看下怎么使用,下面是伪代码

err := this.QueryTable(this.table).Filter("id", id).One(data)if err != nil && err != orm.ErrNoRows {return err}return nil

这种其实在Golang 源码或者第三方类库里面用的比较多,缺点就是耦合,调用者使用一个第三方类库,需要知道的它的代码里面的错误类型,而且还需要在项目中使用这些错误类型的变量进行比较,第一次使用的开发者,很难想到需要这么使用。

2.自定义自己的Error

以前PHP的项目Exception里面会定义自己的错误码 code。
Golang中我们也可以定义自己的Error类型,然后使用断言决定是那种Error来获取更多的错误数据,看下下面的示例代码,了解下自定义Error的简单使用

type SelfError struct {Code intErr error}func (this *SelfError) Error() string {return this.Err.Error()}func (this *SelfError) GetCode() int {return this.Code}func OpenFile(name string) error {err := os.Rename("/tmp/test","/tmp/test1")if err != nil {return &SelfError{-1001, err}}return nil}func main() {err := OpenFile("test")switch erro := err.(type) {case nil:fmt.Println("success")case *SelfError:fmt.Println(erro.Error(),erro.Code)case error:fmt.Println(erro.Error())}}

还有一种用法就是判断error类型是否是自定义如果是,就返回自定义的属性

func main() {err := OpenFile("test")serr, ok := err.(*SelfError)if ok {fmt.Println(serr.GetCode())}}

可以看到都是通过断言去判断error是否是自定义的Error,如果是,就使用自定义的Error自己的属性和方法。

耦合,调用者需要使用switch或者断言才能使用自定义的Error的属性。

3.Wrap Errors的使用

wrap errors的使用应该是项目对error的处理运用最多的一种,可以方便的加入使用时的上下文。
Wrap Errors 顾名思义就是把error一层层的包装,最外层拿到的是error的一个堆栈信息,根据堆栈信息一直可以追踪到第一个引起error 的调用代码。
需要使用这个包

github.com/pkg/errors

看下代码示例

package mainimport ("fmt""github.com/pkg/errors""os")func ModelFile() error {err := os.Rename("/tmp/test","/tmp/test1")if err != nil {return errors.Wrap(err, "model_rename_fail")}return nil}func LogicFile() error {err := ModelFile()if err != nil {return errors.Wrap(err, "logic_rename_fail")}return nil}func main() {err := LogicFile()if err != nil {fmt.Printf("error:%v", errors.Cause(err))fmt.Printf("%+v", err)}}

看下执行结果的堆栈

error:rename /tmp/test /tmp/test1: no such file or directoryrename /tmp/test /tmp/test1: no such file or directorymodel_rename_failmain.ModelFile        /data/www/go/class="lazy" data-src/test1/main.go:12main.LogicFile        /data/www/go/class="lazy" data-src/test1/main.go:18main.main        /data/www/go/class="lazy" data-src/test1/main.go:26runtime.main        /usr/local/go/class="lazy" data-src/runtime/proc.go:203runtime.goexit        /usr/local/go/class="lazy" data-src/runtime/asm_amd64.s:1357logic_rename_failmain.LogicFile        /data/www/go/class="lazy" data-src/test1/main.go:20main.main        /data/www/go/class="lazy" data-src/test1/main.go:26runtime.main        /usr/local/go/class="lazy" data-src/runtime/proc.go:203runtime.goexit        /usr/local/go/class="lazy" data-src/runtime/asm_amd64.s:1357

使用的简单规则

这么多使用方法,到底应该用哪一种,大致建议应该是这样的

  • 需要做比较错误类型的时候,肯定是第一种方式使用,目前也没有更好的方式

  • 需要加入自己项目的错误码或者复杂的一些上下文,可能就需要使用第二种自定义错误类型

  • 需要依赖第三方的类库,这个类库可能也不太稳定,那么wrap error优势就比较明显,可以打印记录堆栈,方便定位。

  • 一些常用的简单项目,就只需在触发错误的地方记录上下文打上日志,直接返回error就可以了,这是最简单最方便的。

关于golang中Error如何使用问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

golang中Error如何使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

golang中Error如何使用

golang中Error如何使用,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Error是Go语言开发中最基础也是最重要的部分,跟其他语言的try catch的作用基本一致
2023-06-20

Golang中如何使用 Iota

这篇文章给大家介绍Golang中如何使用 Iota,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。如何实现枚举iota 是 Go 中预声明的一个特殊常量。它会被预声明为0,但是它的值在编译阶段并非是固定的,当预声明的 i
2023-06-15

golang中如何使用JSON

今天小编给大家分享一下golang中如何使用JSON的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。JSON是一种通用的数据交
2023-07-06

golang中ssh包如何使用

本篇文章给大家分享的是有关golang中ssh包如何使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、ssh包crypto的安装ssh使用的包为"golang.org/x/
2023-06-06

如何在golang 中使用Logrus

如何在golang 中使用Logrus?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。golang Logrus简易使用教程使用Logrus的最简单方法:package ma
2023-06-15

Golang中的consul如何使用

这篇文章主要介绍“Golang中的consul如何使用”,在日常操作中,相信很多人在Golang中的consul如何使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang中的consul如何使用”的疑
2023-07-05

Golang中quicktemplate库如何使用

Golang中quicktemplate库如何使用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。先创建代码目录并初始化:$ mkdir quicktemplate && cd
2023-06-20

golang 中slice和string如何使用

这期内容当中小编将会给大家带来有关golang 中slice和string如何使用,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。slice 和 string 内部结构slice 和 string 的内部结
2023-06-20

Golang中Slice切片如何使用

今天小编给大家分享一下Golang中Slice切片如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。上代码func ma
2023-07-05

如何在Golang中使用协程

这篇文章将为大家详细讲解有关如何在Golang中使用协程,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。什么是golanggolang 是Google开发的一种静态强类型、编译型、并发型,并具
2023-06-14

如何在Golang中使用模板

Golang使用模板的步骤:1、用go get命令安装模板引擎;2、创建一个包含占位符的文本文件;3、使用Parse()方法解析模板;4、使用Execute()方法渲染模板;5、模板变量的解析;6、如果模板需要包含子模板,可以进行模板嵌套;
如何在Golang中使用模板
2023-12-12

Docker API如何在Golang中使用

Docker API如何在Golang中使用?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。安装 SDK通过下面的命令就可以安装 SDK 了:go get github.com/
2023-06-14

如何在golang中使用cobra库

如何在golang中使用cobra库?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。cobra 是 go 语言的一个库,可以用于编写命令行工具。通常我们可以看到
2023-06-15

如何在 Golang 中使用事务?

在 go 中,可以使用 tx 类型进行事务操作。要开启事务,请使用 db.begin()。在事务块中,执行数据库操作,如查询、更新。执行成功后,使用 tx.commit() 提交事务。在实战中,事务可确保并发操作的一致性,如同时更新库存和创
如何在 Golang 中使用事务?
2024-05-14

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录