试了下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中什么是nil
Apr 29 Golang
golang goroutine顺序输出方式
Apr 29 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
golang gopm get -g -v 无法获取第三方库的解决方案
May 05 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
浅谈GO中的Channel以及死锁的造成
Mar 18 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
golang生成并解析JSON
Apr 14 Golang
Go web入门Go pongo2模板引擎
May 20 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
用缓存实现静态页面的测试
2006/12/06 PHP
php 静态变量的初始化
2009/11/15 PHP
apache+php完美解决301重定向的两种方法
2011/06/08 PHP
PHP的SQL注入过程分析
2012/01/06 PHP
PHP5多态性与动态绑定介绍
2015/04/03 PHP
原生JavaScript编写俄罗斯方块
2015/03/30 Javascript
JavaScript数值千分位格式化的两种简单实现方法
2016/08/01 Javascript
JS验证图片格式和大小并预览的简单实例
2016/10/11 Javascript
微信小程序 监听手势滑动切换页面实例详解
2017/06/15 Javascript
webpack实现热加载自动刷新的方法
2017/07/30 Javascript
基于LayUI分页和LayUI laypage分页的使用示例
2017/08/02 Javascript
Vue 中mixin 的用法详解
2018/04/23 Javascript
利用Promise自定义一个GET请求的函数示例代码
2019/03/20 Javascript
React生命周期原理与用法踩坑笔记
2020/04/28 Javascript
vue实现简易图片左右旋转,上一张,下一张组件案例
2020/07/31 Javascript
微信小程序实现电影App导航和轮播
2020/11/30 Javascript
python实现猜数字游戏(无重复数字)示例分享
2014/03/29 Python
python通过线程实现定时器timer的方法
2015/03/16 Python
详解Python使用simplejson模块解析JSON的方法
2016/03/24 Python
Python编程实现线性回归和批量梯度下降法代码实例
2018/01/04 Python
pygame游戏之旅 按钮上添加文字的方法
2018/11/21 Python
在python中利用KNN实现对iris进行分类的方法
2018/12/11 Python
python3用urllib抓取贴吧邮箱和QQ实例
2020/03/10 Python
如何基于Python Matplotlib实现网格动画
2020/07/20 Python
Python中正则表达式对单个字符,多个字符和匹配边界等使用
2021/01/27 Python
HTML5 DeviceOrientation实现手机网站摇一摇功能代码实例
2015/04/24 HTML / CSS
国际花店:Pickup Flowers
2020/04/10 全球购物
可以在一个PHP文件里面include另外一个PHP文件两次吗
2015/05/22 面试题
SQL注入攻击的种类有哪些
2013/12/30 面试题
纪律教育学习月活动总结
2014/08/27 职场文书
股东授权委托书范本
2014/09/13 职场文书
户籍证明模板
2014/09/28 职场文书
个人整改措施书面材料
2014/10/24 职场文书
我的生日感言
2015/08/03 职场文书
python运行脚本文件的三种方法实例
2022/06/25 Python
PostgreSQL逻辑复制解密原理解析
2022/09/23 PostgreSQL