go语言的语法学起来仍是比较快的,但在实战过程当中总会遇到这样或那样的错误,逐个解决领悟以后,才能真正掌握go语言的细枝末节,成为一名合格的gopher
。app
废话很少说,先吃几个栗子:函数
var a int, b int, c int
复制代码
package main
s := "china"
func main() {
}
复制代码
s := make([]int, 5)
s = append(s, 1, 2, 3)
fmt.Println(s)
复制代码
怎么样,是否是找到一丢丢感受了呀 : )ui
===============================spa
今天第一节(儿童节也阔以愉快的写博客~),分享几点defer
的细枝末节:code
func main() {
deferCall()
}
func deferCall() {
defer func() {
fmt.Println("打印前")
/*if err := recover(); err != nil { fmt.Println(err) }*/
}()
defer func() { fmt.Println("打印中") }()
defer func() { fmt.Println("打印后") }()
panic("触发异常")
}
复制代码
【解析】当 defer
与 panic
处于同一个 goroutine
中,defer
会试图去recover
(注释部分),此时因为没有 recover
进行捕获,所以会出现以下几种输出:orm
a.
“触发异常”
“打印后”
“打印中”
“打印前”
b.
“打印后”
“打印中”
“打印前”
“触发异常”
c.
“打印后”
“触发异常”
“打印中”
“打印前”
复制代码
出现以上几种不一样的输出结果,笔者的理解(欢迎讨论~)是打印到 stdout
的 print
函数在同一时刻争抢的结果,由于程序的实际执行顺序是:遇到panic
,先执行 defer
中 fmt.Println
后,再输出 panic
本身的报错。cdn
defer
被声明时,其参数就会被实时解析func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
a := 1
b := 2
defer calc("1", a, calc("10", a, b))
a = 0
defer calc("2", a, calc("20", a, b))
b = 1
}
复制代码
【解析】当 defer 被调用时,a, b 会取当前实时解析值,并先计算defer
里层 calc
的值保存下来,最后再执行defer
外层 calc
函数,所以输出结果为:博客
10 1 2 3
20 0 2 2
2 0 2 2
1 1 3 4
复制代码
package main
import "fmt"
func main() {
v := c()
fmt.Println(v)
}
func c() (i int) {
defer func() { i++ }()
return 1
}
复制代码
【解析】当 defer
返回时,获取到返回值 i = 1
,进行 defer
里面的 i++
,因此返回输出是2,而不是1。string
以上就是今天分享的关于 defer
的几个point,这些硬知识看书很容易忽略,在实战中才能更好的掌握,keep moving~it