关于php:优化-Go-错误处理魔改-Go-recover-靠谱吗

5次阅读

共计 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 源码
正文完
 0