试了下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 Gin实现文件上传下载的示例代码
Apr 02 Golang
go语言中切片与内存复制 memcpy 的实现操作
Apr 27 Golang
Go语言切片前或中间插入项与内置copy()函数详解
Apr 27 Golang
彻底理解golang中什么是nil
Apr 29 Golang
golang import自定义包方式
Apr 29 Golang
解决Goland 同一个package中函数互相调用的问题
May 06 Golang
基于Golang 高并发问题的解决方案
May 08 Golang
Go语言基础切片的创建及初始化示例详解
Nov 17 Golang
Golang 链表的学习和使用
Apr 19 Golang
Golang 实现WebSockets
Apr 24 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
go goth封装第三方认证库示例详解
Aug 14 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中显示格式化的用户输入
2006/10/09 PHP
IIS环境下快速安装、配置和调试PHP5.2.0
2006/12/17 PHP
php 变量未定义等错误的解决方法
2011/01/12 PHP
windows下的WAMP环境搭建图文教程(推荐)
2017/07/27 PHP
处理及遍历XML文档DOM元素属性及方法整理
2013/08/23 Javascript
javascript history对象(历史记录)使用方法(实现浏览器前进后退)
2014/01/07 Javascript
解决jquery操作checkbox火狐下第二次无法勾选问题
2014/02/10 Javascript
Jquery获得控件值的三种方法总结
2014/02/13 Javascript
javascript cookie的基本操作(添加和删除)
2017/07/24 Javascript
js前端导出Excel的方法
2017/11/01 Javascript
webpack构建换肤功能的思路详解
2017/11/27 Javascript
layui的table中显示图片方法
2018/08/17 Javascript
js将URL网址转为16进制加密与解密函数
2020/03/04 Javascript
vue element ui validate 主动触发错误提示操作
2020/09/21 Javascript
Python3基础之list列表实例解析
2014/08/13 Python
Python的设计模式编程入门指南
2015/04/02 Python
python操作ie登陆土豆网的方法
2015/05/09 Python
python过滤字符串中不属于指定集合中字符的类实例
2015/06/30 Python
python 递归遍历文件夹,并打印满足条件的文件路径实例
2017/08/30 Python
Python与R语言的简要对比
2017/11/14 Python
Python操作mysql数据库实现增删查改功能的方法
2018/01/15 Python
tensorflow 模型权重导出实例
2020/01/24 Python
python不相等的两个字符串的 if 条件判断为True详解
2020/03/12 Python
在Django中自定义filter并在template中的使用详解
2020/05/19 Python
python安装读取grib库总结(推荐)
2020/06/24 Python
Python Matplotlib简易教程(小白教程)
2020/07/28 Python
英国高街品牌:Miss Selfridge(塞尔弗里奇小姐)
2016/09/21 全球购物
自学考试自我鉴定范文
2013/09/26 职场文书
领导证婚人证婚词
2014/01/13 职场文书
离婚协议书样本
2015/01/26 职场文书
酒店服务员岗位职责
2015/02/09 职场文书
入党积极分子个人总结
2015/03/02 职场文书
2016公司年会通知范文
2015/04/25 职场文书
大学社团活动总结怎么写
2019/06/21 职场文书
详解SpringBoot异常处理流程及原理
2021/06/21 Java/Android
MySql 8.0及对应驱动包匹配的注意点说明
2021/06/23 MySQL