go语言的语法学起来还是比较快的,但在实战过程中总会遇到这样或那样的错误,逐个解决领悟之后,才能真正掌握go语言的细枝末节,成为一名合格的gopher。

废话不多说,先吃几个栗子:
- 下面的变量定义是否正确?
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)
怎么样,是不是找到一丢丢感觉了呀 : )
===============================
今天第一节,分享几点defer的细枝末节:
Defer规则一:下面的语句会触发panic吗?
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 进行捕获,因此会出现如下几种输出:
a. “触发异常” “打印后” “打印中” “打印前” b. “打印后” “打印中” “打印前” “触发异常” c. “打印后” “触发异常” “打印中” “打印前”
出现以上几种不同的输出结果,笔者的理解(欢迎讨论~)是打印到 stdout 的 print函数在同一时刻争抢的结果,因为程序的实际执行顺序是:遇到panic,先执行 defer 中 fmt.Println 后,再输出 panic 自己的报错。
Defer规则二:当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
Defer规则三:可以读取有名返回值
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。
以上就是今天分享的关于 defer 的几个point,这些硬知识看书很容易忽略,在实战中才能更好的掌握,keep moving~