试了下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语言操作数据库及其常规操作的示例代码
Apr 21 Golang
win10下go mod配置方式
Apr 25 Golang
golang通过递归遍历生成树状结构的操作
Apr 28 Golang
Golang Gob编码(gob包的使用详解)
May 07 Golang
Golang 实现获取当前函数名称和文件行号等操作
May 08 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
golang 实用库gotable的具体使用
Jul 01 Golang
基于Go语言构建RESTful API服务
Jul 25 Golang
深入理解go slice结构
Sep 15 Golang
Go语言 详解net的tcp服务
Apr 14 Golang
详解Go语言中配置文件使用与日志配置
Jun 01 Golang
Go gRPC进阶教程gRPC转换HTTP
Jun 16 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
Yii2 队列 shmilyzxt/yii2-queue 简单概述
2017/08/02 PHP
Ubuntu上安装yaf扩展的方法
2018/01/29 PHP
javascript延时重复执行函数 lLoopRun.js
2007/06/29 Javascript
jquery实现点击查看更多内容控制段落文字展开折叠效果
2015/08/06 Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
2016/09/05 Javascript
JavaScript数组去重的几种方法效率测试
2016/10/23 Javascript
Vue中父组件向子组件通信的方法
2017/07/11 Javascript
Vuejs在v-for中,利用index来对第一项添加class的方法
2018/03/03 Javascript
vue项目打包后打开页面空白解决办法
2018/06/29 Javascript
使用python提取html文件中的特定数据的实现代码
2013/03/24 Python
详细介绍Python的鸭子类型
2016/09/12 Python
Python解析json之ValueError: Expecting property name enclosed in double quotes: line 1 column 2(char 1)
2017/07/06 Python
python 创建弹出式菜单的实现代码
2017/07/11 Python
Python实现利用163邮箱远程关电脑脚本
2018/02/22 Python
Python操作mongodb的9个步骤
2018/06/04 Python
python实现字符串中字符分类及个数统计
2018/09/28 Python
Python 字符串、列表、元组的截取与切片操作示例
2019/09/17 Python
Python安装与卸载流程详细步骤(图解)
2020/02/20 Python
python3通过udp实现组播数据的发送和接收操作
2020/05/05 Python
Python如何实现邮件功能
2020/05/27 Python
10分钟理解CSS3 Grid布局
2018/12/20 HTML / CSS
马来西亚时装购物网站:ZALORA马来西亚
2017/03/14 全球购物
沙特阿拉伯家用电器和电子产品购物网站:Sheta and Saif
2020/04/03 全球购物
描述Cookie和Session的作用,区别和各自的应用范围,Session工作原理
2015/03/25 面试题
普天C++笔试题
2016/03/20 面试题
夜班门卫岗位职责
2013/12/09 职场文书
大学生职业生涯规划书前言
2014/01/09 职场文书
高中学生评语大全
2014/04/25 职场文书
村抢险救灾方案
2014/05/09 职场文书
推广普通话标语
2014/06/27 职场文书
五月的鲜花活动方案
2014/08/21 职场文书
新疆民族团结演讲稿
2014/08/27 职场文书
民主生活会汇报材料
2014/12/15 职场文书
八年级英语教学计划
2015/01/23 职场文书
2015年安康杯竞赛活动总结
2015/03/26 职场文书
运动会观后感
2015/06/09 职场文书