脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - 用 Switch-case 来解决 Go 错误处理的难题?

用 Switch-case 来解决 Go 错误处理的难题?

2024-02-28 16:39脑子进煎鱼了 Golang

今天给大家分享了我所看到的一个 Go 错误处理的新提案,其本质上是利用 switch-case 的新语法机制,实现了 err 变量和 case 的关联。以此简化错误检查的逻辑。

大家好,我是煎鱼。

在 Go 这门编程语言中,if err != nil 的错误处理方式,是我们一直关注的焦点之一。所有的 Go 社区调查中,都有希望优化和改进错误处理的声音和各种想法。

春节期间刷到了一个由 @Bill Soudan 提出的新提案《proposal: Go 2: support new form of switch statement during variable assignment which jumps to function-wide case blocks[1]》,是针对错误处理优化的,思路还是有些新奇的。

用 Switch-case 来解决 Go 错误处理的难题?图片

以往印象里没有人提过这个方式。今天分享给大家,一起围观和学习!

新提案

该提案希望在变量赋值时能够支持新的 switch 语句形式。从功能出发,更具体指的是:要支持 switch 跳转到函数范围内的任意位置的标签。

这个特性的目的是:简化繁琐又重复的 if err !=nil 的错误检查代码,也可以用于其他逻辑实现。

具体的对比例子如下。

如果是原本的 Go1 错误处理的范式。

代码如下:

func CopyFile(src, dst string) error {
 r, err := os.Open(src)
 if err != nil {
  return err
 }
 defer r.Close()

 w, err := os.Create(dst)
 if err != nil {
  return err
 }
 defer w.Close()

 if _, err := io.Copy(w, r); err != nil {
  return err
 }
 if err := w.Close(); err != nil {
  return err
 }
}

要写比较多的判断和返回错误的逻辑,并且这些代码比正式的调用代码还要多。所以也常被人戏称一个 Go 工程里 80% 都是 if err != nil 等错误检查代码。

基于本文提到的 switch-case 提案进行改造。

新的代码如下:

func CopyFile(src, dst string) error {
 r, switch err := os.Open(src)
 defer r.Close()

 w, switch err := os.Create(dst)
 defer w.Close()

 _, switch dstErr := io.Copy(w, r)
 switch dstErr = w.Close()

 return nil

case dstErr != nil:
 os.Remove(dst)
 err = dstErr
 fallthrough

case err != nil:
 return fmt.Errorf("copy %s %s: %v", src, dst, err)
}

注意几个细节点:

  • switch 关键字在对应的 err 变量前作为声明标识。
  • case 关键字根据对应的 err 变量,运行不同的错误处理逻辑。
  • switch-case 子句可以在同一函数内的不同位置进行调用。

这种 switch-case 的使用方式,从优点来看。确实收拢了统一的错误处理逻辑,减少了重复繁琐的代码量。

短短的代码片段,看起来像那么一回事,能一定程度上满足大家原始的诉求。

缺点的话,个人认为会增加认知和逻辑复杂度。你根本不知道 switch-case,这个 case 他的准确逻辑位置在哪里。

一旦有人套娃,就非常麻烦了。同时 switch-case 延伸出多种不同的使用方式,会产生二义性,这是一个折腾的事情。

总结

今天给大家分享了我所看到的一个 Go 错误处理的新提案,其本质上是利用 switch-case 的新语法机制,实现了 err 变量和 case 的关联。以此简化错误检查的逻辑。

软件开发是没有银弹的。如何引入更优雅的错误处理机制,且不要带过来过大的程序员心智负担,还要要确保编译器性能尚可。Go 核心团队可能是想要在这三个圈里设计一个最优的选择。

参考资料

[1]

proposal: Go 2: support new form of switch statement during variable assignment which jumps to function-wide case blocks: https://github.com/golang/go/issues/65019

原文地址:https://mp.weixin.qq.com/s/MkWxrN_kQFNn9rMeJXs3PA

延伸 · 阅读

精彩推荐
  • Golang深入理解go缓存库freecache的使用

    深入理解go缓存库freecache的使用

    go开发缓存场景一般使用map或者缓存框架,为了线程安全会使用sync.Map或线程安全的缓存框架,本文就详细的介绍了go缓存库freecache,感兴趣的可以了解一下...

    luoxn286522022-09-03
  • GolangGolang易错知识点汇总

    Golang易错知识点汇总

    这篇文章汇总了在开发和刷面试题过程中遇到的Golang容易搞错的知识点,关键部分也都为大家写了代码示例,感兴趣的小伙伴可以了解一下...

    王中阳Go7072022-09-07
  • Golang初识Golang Mutex互斥锁的使用

    初识Golang Mutex互斥锁的使用

    在学习操作系统的时候,我们应该都学习过临界区、互斥锁这些概念,用于在并发环境下保证状态的正确性。在 Go语言 里面互斥锁是 sync.Mutex ,我们本篇文...

    漫漫Coding路10002022-11-25
  • Golang详解golang中的闭包与defer

    详解golang中的闭包与defer

    闭包一个函数与其相关的引用环境组合的一个实体,其实可以理解为面向对象中类中的属性与方法,这篇文章主要介绍了golang的闭包与defer,需要的朋友可以...

    MY.BOO12042022-11-15
  • Golanggolang elasticsearch Client的使用详解

    golang elasticsearch Client的使用详解

    这篇文章主要介绍了golang elasticsearch Client的使用详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    insisxz9862021-06-18
  • GolangHugo Config模块构建实现源码剖析

    Hugo Config模块构建实现源码剖析

    这篇文章主要为大家介绍了Hugo Config模块构建实现源码剖析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪...

    GitAction7312023-02-26
  • GolangGolang算法之田忌赛马问题实现方法分析

    Golang算法之田忌赛马问题实现方法分析

    这篇文章主要介绍了Golang算法之田忌赛马问题实现方法,结合具体实例形式分析了基于Go语言的田忌赛马问题原理与算法实现技巧,需要的朋友可以参考下 ...

    books19582182020-05-05
  • GolangGO 语言运行环境的基础知识

    GO 语言运行环境的基础知识

    这篇文章主要介绍了GO 语言运行环境的基础知识的相关资料,需要的朋友可以参考下...

    芒果和小猫10182022-11-21