Go错误处理:用select-case来解决
Go错误处理
为网友解答Go错误处理的相关经验,请看下面详细的介绍。
日常看Go社区的一些新动态,发现大家对于错误处理的新提案是很积极。
这几天又整出来个select-case的新提案的方式来解决错误处理。
今天基于此给大家分享一下社区里的新脑洞。
快速背景
本节的背景主要是给不了解的同学拉通一下。如果已经知道的可以跳过本节。新提案的提出背景,与之前的类似。
社区内的Go开发者很多嫌弃 if err != nil 的错误处理方式过于繁琐,纷纷提出各种改进方式和新提案。
截至目前暂无大改进被通过。
具体演示代码如下:
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
}
// IT袋网...
}
要写比较多的判断和返回错误的逻辑,并且这些代码比正式的调用代码还要多。
所以也常被人戏称一个 Go 工程里 80% 都是 if err != nil 等错误检查代码。
新提案
本次新提案是由 @bjorndm 提出的 《proposal: Go 2: add trap on direct assignment with select block》:

提出者本身使用编程语言的经验比较丰富,用过:C, Ruby, Pascal, Basic, Java, Shell 等。本次提出该提案的原因是某些 shell 中 trap 语句的启发。
抽象了一下,提案内容如下:
- 功能上是要扩展 select 关键字的语法,允许在 select 关键字和其代码块之间放一个单独的变量,这会在变量上安装一个 “陷阱”(类似触发器)。
- 这个 “陷阱” 是关键点,当任何值被赋给该变量时将会触发。然后在 select 代码块的主体中,case 语句可用于检查变量的值。
从原作者的描述来看,提案内容比较生硬。我们结合演示代码来看就知道,他是想构思什么新语法来使用 select-case 达到错误处理的目的了。
演示代码如下:
func CanFail(name string) error {
var err error
select err {
case err != nil:
return fmt.Errorf("CanFail: %w", err)
}
fin, err := os.Open(name)
buf, err := io.ReadAll(fin)
return nil
}
结合新提案的语法,由于 select 代码块中是一个变量,符合新语法 “陷阱” 的场景。
因此err变量被安装了 “陷阱”,当后面的 os.Open 和 io.ReadAll 等方法赋值给err变量时,就能触发select子句的 case检查。
最终以此达到简化 if err != nil 的目的。也可以满足Go1兼容性保障,达到向前和向后兼容,不需要新增关键字。
相关阅读
-
城域网 MAN的特点有哪些?
小编为大家解答城域网 MAN的特点有哪些?的内容,请看下面详细的介绍。 城域网(Metropolitan Area Network)覆盖比LAN更大的地理区域,通常涵盖整个城市或城市区域。 特点 中等范围: MAN的覆盖
-
成都网页制作公司有哪些 网页设计制作网站
小编为大家解答成都网页制作公司有哪些和网页设计制作网站的内容,一定能解决您的问题的,一起来了解吧! 随着时代的快速发展,现在已经进入了信息时代。随着网络的春风,不光是能够
-
ping ttl传输中过期是什么原因和解决方法介绍
常在河边走,哪有不湿鞋,有时候就连网络维护人员可能都会遇到 ping ip时报TTL传输过期 的问题,不知道是什么原因引起的,下面IT袋小编就给大家分享下哪些原因会引起 ping ttl传输中过期 。
-
spring如何解决循环依赖的问题
小编为你解答spring如何解决循环依赖的问题方面的讲解,一起来了解了解吧。 循环依赖指的是两个类中的属性相互依赖对方:例如 A 类中有 B 属性,B 类中有 A属性,从而形成了一个依赖闭环,


