试了下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语言中切片与内存复制 memcpy 的实现操作
Apr 27 Golang
go 原生http web 服务跨域restful api的写法介绍
Apr 27 Golang
解决golang在import自己的包报错的问题
Apr 29 Golang
golang 在windows中设置环境变量的操作
Apr 29 Golang
浅谈golang package中init方法的多处定义及运行顺序问题
May 06 Golang
go mod 安装依赖 unkown revision问题的解决方案
May 06 Golang
Golang全局变量加锁的问题解决
May 08 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
Go语言安装并操作redis的go-redis库
Apr 14 Golang
深入理解 Golang 的字符串
May 04 Golang
详解Go语言中Get/Post请求测试
Jun 01 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通过前序遍历树实现无需递归的无限极分类
2015/07/10 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
手机平板等移动端适配跳转URL的js代码
2014/01/25 Javascript
javascript获取函数名称、函数参数、对象属性名称的代码实例
2014/04/12 Javascript
Jquery操作js数组及对象示例代码
2014/05/11 Javascript
js实现用户注册协议倒计时的方法
2015/01/21 Javascript
vue实现登陆登出的实现示例
2017/09/15 Javascript
Vue结合SignalR实现前后端实时消息同步
2017/09/19 Javascript
echarts学习笔记之图表自适应问题详解
2017/11/22 Javascript
Vue二次封装axios为插件使用详解
2018/05/21 Javascript
Bootstrap开发中Tab标签页切换图表显示问题的解决方法
2018/07/13 Javascript
Vue $emit $refs子父组件间方法的调用实例
2018/09/12 Javascript
微信小程序的线程架构【推荐】
2019/05/14 Javascript
ES6 Promise对象的应用实例分析
2019/06/27 Javascript
layui switch 开关监听 弹出确定状态转换的例子
2019/09/21 Javascript
js消除图片小游戏代码
2019/12/11 Javascript
jQuery AJAX应用实例总结
2020/05/19 jQuery
python计算对角线有理函数插值的方法
2015/05/07 Python
python机器人行走步数问题的解决
2018/01/29 Python
如何使用pycharm连接Databricks的步骤详解
2020/09/23 Python
Python定时任务框架APScheduler原理及常用代码
2020/10/05 Python
Django启动时找不到mysqlclient问题解决方案
2020/11/11 Python
Html5页面上如何禁止手机虚拟键盘弹出
2020/03/19 HTML / CSS
空指针到底是什么
2012/08/07 面试题
2014年预备党员学习两会心得体会
2014/03/17 职场文书
工作说明书范文
2014/05/07 职场文书
大学活动总结模板
2014/07/10 职场文书
售后服务承诺函格式
2015/01/21 职场文书
2015年保卫科工作总结
2015/05/14 职场文书
红白喜事主持词
2015/07/06 职场文书
教师节获奖感言
2015/07/31 职场文书
宝宝满月祝酒词
2015/08/10 职场文书
2016年“12.4”法制宣传日活动总结
2016/04/01 职场文书
MySQL Innodb关键特性之插入缓冲(insert buffer)
2021/04/08 MySQL
Python 中数组和数字相乘时的注意事项说明
2021/05/10 Python
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL