试了下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语言中的UTF-8实现
Apr 26 Golang
对Golang中的FORM相关字段理解
May 02 Golang
golang switch语句的灵活写法介绍
May 06 Golang
Golang二维数组的使用方式
May 28 Golang
再次探讨go实现无限 buffer 的 channel方法
Jun 13 Golang
入门学习Go的基本语法
Jul 07 Golang
Golang中channel的原理解读(推荐)
Oct 16 Golang
一文搞懂Golang 时间和日期相关函数
Dec 06 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
Go语言 详解net的tcp服务
Apr 14 Golang
golang生成并解析JSON
Apr 14 Golang
Golang 并发编程 SingleFlight模式
Apr 26 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
Ajax PHP分页演示
2007/01/02 PHP
深入解析php模板技术原理【一】
2008/01/10 PHP
php输出echo、print、print_r、printf、sprintf、var_dump的区别比较
2013/06/21 PHP
shell脚本作为保证PHP脚本不挂掉的守护进程实例分享
2013/07/15 PHP
php把session写入数据库示例
2014/02/26 PHP
Thinkphp模板中截取字符串函数简介
2014/06/17 PHP
PHP获取远程图片并保存到本地的方法
2015/05/12 PHP
PHP file_get_contents函数读取远程数据超时的解决方法
2015/05/13 PHP
实例讲解如何在PHP的Yii框架中进行错误和异常处理
2016/03/17 PHP
PHP读取文件的常见几种方法
2016/11/03 PHP
JavaScript For Beginners(转载)
2007/01/05 Javascript
避免回车键导致的页面无意义刷新的解决方法
2011/04/12 Javascript
JS自动适应的图片弹窗实例
2013/06/29 Javascript
JQuery查找DOM节点的方法
2015/06/11 Javascript
js实现TAB切换对应不同颜色的代码
2015/08/31 Javascript
JS批量替换内容中关键词为超链接
2017/02/20 Javascript
使用Vue完成一个简单的todolist的方法
2017/12/01 Javascript
jQuery实现的回车触发按钮事件功能示例
2018/03/25 jQuery
你点的 ES6一些小技巧,请查收
2018/04/25 Javascript
在Node.js下运用MQTT协议实现即时通讯及离线推送的方法
2019/01/24 Javascript
vue组件间的参数传递实例详解
2019/04/26 Javascript
基于vue实现一个神奇的动态按钮效果
2019/05/15 Javascript
Javascript模块化机制实现原理详解
2020/04/02 Javascript
[51:44]2018DOTA2亚洲邀请赛 4.3 突围赛 Optic vs iG 第二场
2018/04/04 DOTA
[50:50]完美世界DOTA2联赛PWL S3 INK ICE vs DLG 第一场 12.20
2020/12/23 DOTA
利用anaconda保证64位和32位的python共存
2021/03/09 Python
Python下载的11种姿势(小结)
2020/11/18 Python
python中使用np.delete()的实例方法
2021/02/01 Python
仪器仪表检测毕业生自荐信
2013/10/31 职场文书
资产经营总监岗位职责
2013/12/04 职场文书
无工作经验者个人求职信范文
2013/12/22 职场文书
校长师德表现自我评价
2015/03/04 职场文书
2016年暑期教师培训心得体会
2016/01/09 职场文书
电力安全学习心得体会
2016/01/18 职场文书
2017元旦、春节期间廉洁自律承诺书
2016/03/25 职场文书
Python Pygame实战之塔防游戏的实现
2022/03/17 Python