试了下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 相关文章推荐
golang判断key是否在map中的代码
Apr 24 Golang
golang 在windows中设置环境变量的操作
Apr 29 Golang
Golang: 内建容器的用法
May 05 Golang
Golang中异常处理机制详解
Jun 08 Golang
再次探讨go实现无限 buffer 的 channel方法
Jun 13 Golang
Go语言设计模式之结构型模式
Jun 22 Golang
Golang 语言控制并发 Goroutine的方法
Jun 30 Golang
一文搞懂Golang 时间和日期相关函数
Dec 06 Golang
Golang ort 中的sortInts 方法
Apr 24 Golang
GoFrame框架数据校验之校验结果Error接口对象
Jun 21 Golang
Go语言测试库testify使用学习
Jul 23 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
中国站长站 For Dede4.0 采集规则
2007/05/27 PHP
php生成随机数或者字符串的代码
2008/09/05 PHP
php 文件上传代码(限制jpg文件)
2010/01/05 PHP
PHP OPP机制和模式简介(抽象类、接口和契约式编程)
2014/06/09 PHP
为你总结一些php信息函数
2015/10/21 PHP
php微信公众平台开发之微信群发信息
2016/09/13 PHP
jQuery 相关控件的事件操作分解
2009/08/03 Javascript
jWiard 基于JQuery的强大的向导控件介绍
2011/10/28 Javascript
javascript面向对象包装类Class封装类库剖析
2013/01/24 Javascript
整理JavaScript对DOM中各种类型的元素的常用操作
2016/05/05 Javascript
JS函数的定义与调用方法推荐
2016/05/12 Javascript
JS禁止浏览器右键查看元素或按F12审查元素自动关闭页面示例代码
2017/09/07 Javascript
react native 文字轮播的实现示例
2018/07/27 Javascript
JavaScript 监听组合按键思路及代码实现
2020/07/28 Javascript
[04:51]TI10典藏宝瓶Ⅱ外观视频展示
2020/08/15 DOTA
python获得文件创建时间和修改时间的方法
2015/06/30 Python
python实现查找两个字符串中相同字符并输出的方法
2015/07/11 Python
在Python的Django框架中加载模版的方法
2015/07/16 Python
基于Python实现通过微信搜索功能查看谁把你删除了
2016/01/27 Python
Django URL传递参数的方法总结
2016/08/28 Python
浅谈Python2.6和Python3.0中八进制数字表示的区别
2017/04/28 Python
Python绘制七段数码管实例代码
2017/12/20 Python
Python实现多进程的四种方式
2019/02/22 Python
python字典一键多值实例代码分享
2019/06/14 Python
python设置环境变量的原因和方法
2019/06/24 Python
解决Tensorflow sess.run导致的内存溢出问题
2020/02/05 Python
安纳塔拉酒店度假村及水疗官方网站:Anantara Hotel
2016/08/25 全球购物
加拿大票务网站:Ticketmaster加拿大
2017/07/17 全球购物
课堂教学改革实施方案
2014/03/17 职场文书
校园歌咏比赛主持词
2014/03/18 职场文书
电脑售后服务承诺书
2014/03/27 职场文书
本科生自荐信
2014/06/18 职场文书
禁止酒驾标语
2014/06/25 职场文书
金榜题名主持词
2015/07/02 职场文书
四年级数学教学反思
2016/02/16 职场文书