今天碰到了一个 recover() 的一个坑。
有一个操作预期可能出现 panic 而且不需要关心它是否panic.就建立了一个匿名函数将操作包裹起来并 追加了 defer recover。 原来都是 defer func(){_=recover()}(),这次省掉了匿名函数,直接 defer recover() 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package main func main(){ defer recover() panic("123") } /* panic: 123 goroutine 1 [running]: main.main() D:/golang/src/github.com/gamexg/go-test/鍩烘湰璇硶/recover娴嬭瘯/1/1.g o:5 +0x97 exit status 2 */ |
结果如上,直接挂了。recover 无效…
查看了 recover 的文档:recover 只能放到 defer 函数里面,不能放到子函数。实测直接 defer recover() 也不行。recover 是内置函数,源码需要到go的实现里面查,懒得去查了。
go 的很多设计感觉都是黑魔法,就像这里,如果 panic 是一个协程本地变量保存的,那么在什么地方调用 recover 都行。但是看情况不是,恐怕和函数调用搅到一起了。
v:=dict[key]、 v,ok:=dict[key] 这个设计也是使用的黑魔法,感觉是一开始只设计了第一种实现,但是由于需要获得是否存在key,就另加了第二个实现,很生硬的感觉。
chan 实现也比较奇怪,连接之类的关闭都是 conn.Close() 实现关闭,chan 却是 close(chan),设计并不统一,很别扭。
ww