试了下Golang实现try catch的方法


Posted in Golang onJuly 01, 2021
目录
  • 前言
  • 能不能 try catch
  • 加入处理异常方法
  • 总结

前言

Golang语言有诸多优点:静态编译、协程、堪比c语言的高性能。

但是也有一些令人发指的地方 —— 经常被人调侃 五行代码,三行错误处理 的异常错误处理方式,如下问题出现的地方

func readFile(path string) ([]byte, error) {
    file, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer file.Close()
    return ioutil.ReadAll(file)
}

函数readFile的功能是读出指定文件本身的内容并将其返回,同时当有错误发生时立即向调用方报告。
根据Golang编程范式,每个可能导致错误的函数都应该将error作为最后一个返回值,所以Golang代码中随处都是"if err != nil"语句。 五行代码,三行错误处理 的调侃段子由此在圈内流行

能不能 try catch

我之前常用编程语言 Python 和 PHP 的时候,早已经习惯 try catch 处理异常的方式。于是对 Golang 使用流程控制 配合 panic()、recover() 一直耿耿于怀,为了以后舒服今天就来实现一下原来 try catch异常错误处理方式

Golang 语言中拥有 recover() 函数作为宕机恢复机制,让程序在宕机流程中的 goroutine 中恢复。

所以我们能够用 recover() 函数作为程序中是否出现的钩子。当出现异常时,由它调起我们的异常处理函数。首先简单实现一下:

package main

import "fmt"

func try(userFn func()) {
 defer func() {
  if err := recover();err != nil{
   fmt.Printf("程序执行发生异常: %v\n", err)
  }
 }()

 userFn()
}

func foo(num int)  {
 if num < 10 {
  panic("number is less than 10")
 }else {
  panic("number is greater than 10")
 }
}

func main()  {
 try(func() {
  foo(9)
 })

 try(func() {
  foo(11)
 })
}

go run main.go 运行:

$ go run _test/demo3/test3.go
程序执行发生异常: number is less than 10
程序执行发生异常: number is greater than 10

从上可以看出,recover() 函数完成我们让它作为钩子,的作用,调起了打印 程序执行发生异常 的信息。

加入处理异常方法

捕抓到异常还需要处理异常,而不是简单打印 程序执行发生异常。所以还需要增加匿名方法作为异常处理方法,改造如下:

func try(userFn func(), catchFn func(err interface{})) {
 defer func() {
  if err := recover();err != nil{
   catchFn(err)
  }
 }()

 userFn()
}

...

func main()  {
 try(func() {
  foo(9)
 }, func(err interface{}) {
  fmt.Printf("程序执行发生异常: %v\n", err)
 })

 try(func() {
  foo(11)
 }, func(err interface{}) {
  fmt.Printf("程序执行发生异常: %v\n", err)
 })
}

这样就可以随心所欲传入自定义处理异常的方法

总结

以上只是自己简单实现了try catch,其中还有很多缺陷,比如:不支持 finally 函数处理,try catch封装过于简单。

到此这篇关于试了下Golang实现try catch的方法的文章就介绍到这了,更多相关Golang try catch内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Golang 相关文章推荐
基于go interface{}==nil 的几种坑及原理分析
Apr 24 Golang
解决Golang中goroutine执行速度的问题
May 02 Golang
golang 比较浮点数的大小方式
May 02 Golang
浅谈golang package中init方法的多处定义及运行顺序问题
May 06 Golang
Golang中异常处理机制详解
Jun 08 Golang
入门学习Go的基本语法
Jul 07 Golang
golang 语言中错误处理机制
Aug 30 Golang
Go语言读取txt文档的操作方法
Jan 22 Golang
Go归并排序算法的实现方法
Apr 06 Golang
Golang 遍历二叉树
Apr 19 Golang
Golang 结构体数据集合
Apr 22 Golang
在ubuntu下安装go开发环境的全过程
Aug 05 Golang
Golang 语言控制并发 Goroutine的方法
Jun 30 #Golang
Golang的继承模拟实例
Jun 30 #Golang
go select编译期的优化处理逻辑使用场景分析
Go 语言下基于Redis分布式锁的实现方式
Jun 28 #Golang
go语言使用Casbin实现角色的权限控制
Go语言设计模式之结构型模式
浅谈Go语言多态的实现与interface使用
Jun 16 #Golang
You might like
PHP实现QQ登录实例代码
2016/01/14 PHP
ThinkPHP删除栏目(实现批量删除栏目)
2017/06/21 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
现代 JavaScript 开发编程风格Idiomatic.js指南中文版
2014/05/28 Javascript
根据配置文件加载js依赖模块
2014/12/29 Javascript
纯js代码实现未知宽高的元素在指定元素中垂直水平居中显示
2015/09/12 Javascript
jQuery插件实现静态HTML验证码校验
2015/11/06 Javascript
基于PHP和Mysql相结合使用jqGrid读取数据并显示
2015/12/02 Javascript
JavaScript原生xmlHttp与jquery的ajax方法json数据格式实例
2015/12/04 Javascript
Bootstrap 组件之按钮(二)
2016/05/11 Javascript
轮播图组件js代码
2016/08/08 Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
2016/09/02 Javascript
Reactjs实现通用分页组件的实例代码
2017/01/19 Javascript
JS FormData上传文件的设置方法
2017/07/05 Javascript
慕课网题目之js实现抽奖系统功能
2017/09/19 Javascript
JavaScript实现邮箱后缀提示功能的示例代码
2018/12/13 Javascript
详解Vue 全局变量,局部变量
2019/04/17 Javascript
python实现简单的计时器功能函数
2015/03/14 Python
Python3简单实例计算同花的概率代码
2017/12/06 Python
基于python requests库中的代理实例讲解
2018/05/07 Python
Python 处理图片像素点的实例
2019/01/08 Python
Python去除字符串前后空格的几种方法
2019/03/04 Python
python中bytes和str类型的区别
2019/10/21 Python
python常用数据重复项处理方法
2019/11/22 Python
python如何实现不用装饰器实现登陆器小程序
2019/12/14 Python
全方位了解CSS3的Regions扩展
2015/08/07 HTML / CSS
Armor Lux法国官方网站:水手服装、成衣和内衣
2020/05/26 全球购物
介绍一下Linux内核的排队自旋锁
2014/01/04 面试题
教师应聘个人求职信
2013/12/10 职场文书
社区反邪教工作方案
2014/06/16 职场文书
处级干部反四风个人对照检查材料思想汇报
2014/09/27 职场文书
大学生自我鉴定怎么写
2019/05/07 职场文书
再读《皇帝的新衣》的读后感悟!
2019/08/07 职场文书
关于 Python json中load和loads区别
2021/11/07 Python
不同品牌、不同型号对讲机如何互相通联
2022/02/18 无线电