共计 1968 个字符,预计需要花费 5 分钟才能阅读完成。
大家好,我是煎鱼。
Go 的错误处理始终是体现最突出的一块中央,许许多多的同学都提出了各种提案,例如:引入 try-catch、用 panic 代替 if err != nil、引入新的关键字等。但这些都被一一驳回了。
不过社区仍然还没放弃,周末看到有一个新的提案《proposal: runtime: add parameters to recover to only return specific types》挺有意思。
明天就由煎鱼带大家一起学习。
语法阐明
Go 的 panic、recover、defer 的根本应用形式。如下代码:
package main
import "fmt"
func mayPanic() {panic("a problem")
}
func main() {defer func() {if r := recover(); r != nil {fmt.Println("Recovered. Error:\n", r)
}
}()
mayPanic()
fmt.Println("After mayPanic()")
}
输入后果:
Recovered. Error:
a problem
新提案
因为有 Go1 兼容性保障,新提案是在原有的 recover 函数上动小手术。心愿能够现 在运行时的 recover 中退出参数,仅反对返回特定的类型。
函数签名:
recover(except ...interface{})
案例代码:
defer func(){if err := recover(&MyError{}, &HelloError{}); err != nil {switch e := err.(type) {
case *MyError:
fmt.Println(e)
case *HelloError:
fmt.Println(e)
}
}
}
下面代码中,recover 函数只反对传入 MyError 和 HelloError 的指针类型。再在解决逻辑中依据所传入的谬误类型,进行断言分类,实际上去做不同的逻辑解决。
重点就是限定 recover 入参类型。
探讨
有些小伙伴可能发现了,比照看看 PHP 的 try-catch 的用法,与后面的提案代码是不是有好几分神似呢?
如下代码:
try {...}
catch (Exception $e) {echo $e->getMessage();
}
catch (InvalidArgumentException $e) {echo $e->getMessage();
}
catch (BarException $ex)
{echo $e->getMessage();
}
catch (FooException $ex)
{echo $e->getMessage();
}
实质上这个新的提案是想在不毁坏 Go1 兼容性的状况下,在 Go 中实现 try-catch 的形式。
社区在交换时,也发现了用户在现有机制下能够自主实现 Go 的类 try-catch 的模式。
如下代码:
func Recover(expect ...interface{}) interface{} {if err := recover(); err != nil {if len(expect) == 0 {return err}
rv1 := reflect.Indirect(reflect.ValueOf(err))
for _, e := range expect {rv2 := reflect.Indirect(reflect.ValueOf(e))
if rv1.Type() == rv2.Type() {return err}
}
panic(err)
}
return nil
}
这个自制办法的问题是每次 Recover panic 都会将堆栈深度减少 2。因而还是寄希望于 Go 官网可能在运行时反对。
在 Go 规范库的用处比照上,也有产生肯定的作用,其波及到的代码根本为:
规范库中至多有以下中央能够复用:
- text/template/exec.go
- go/parser/interface.go
- go/types/check.go
- go/ast/print.go
- encoding/json/encode.go
- encoding/gob/error.go
总结
这个提案实质上是心愿通过在 recover 函数中减少入参管制,再配合外部逻辑实现相似 Go 版本的 try-catch 的错误处理机制模型,且理论在 Go 规范库中有复用的空间。
但现阶段该提案也是同意和拥护参半,也有人认为能够用户本人实现,那就没必要加大复杂度,去做这个收益不够大的实现。
你感觉这能补全 Go 错误处理的一些机制缺点吗?
文章继续更新,能够微信搜【脑子进煎鱼了】浏览,本文 GitHub github.com/eddycjy/blog 已收录,学习 Go 语言能够看 Go 学习地图和路线,欢送 Star 催更。
Go 图书系列
- Go 语言入门系列:初探 Go 我的项目实战
- Go 语言编程之旅:深刻用 Go 做我的项目
- Go 语言设计哲学:理解 Go 的为什么和设计思考
- Go 语言进阶之旅:进一步深刻 Go 源码