package mainimport "fmt"func df()int{i:=5defer func(){i = i + 10fmt.Println("defer函数中的i:",i)}()fmt.Println("df中的i:",i)return i
}
func main(){ri := df()fmt.Println(ri)
}
结果:package mainimport "fmt"func df()int{i:=5defer func(j int){j = j + 10fmt.Println("defer函数中的j:",j)}(i + 1)i=i+30return i
}
func main(){ri := df()fmt.Println(ri)
}
结果:package mainimport "fmt"func df()int{i:=5defer func(j int){j = j + 10fmt.Println("defer函数1中的j:",j)}(i + 1)defer func(j int){j = j + 20fmt.Println("defer函数2中的j:",j)}(i + 1)defer func(j int){j = j + 30fmt.Println("defer函数3中的j:",j)}(i + 1)return i
}
func main(){ri := df()fmt.Println(ri)
}
结果:(1)延迟执行:defer关键字后的函数都是在整个函数执行结束return之后才执行的。正如上述例1代码中最终df函数的返回值是5而不是15,且先执行打印“df中的i”再执行打印“defer函数中的i”所示。上述代码是先执行完df函数中除了defer后面的函数之外的语句。return i(i的值依旧是5)之后,再执行defer后面的函数,执行i = i +10,且打印i
(2)参数预计算:defer函数的形参会在定义时就完成了该参数的拷贝。正如上述例2代码中传入到defer后面函数的形参j的实参i+1不是35,而是6。
(3)FILO:先进后出,若多个defer函数在同一函数内,执行顺序遵循先进后出原理。即第一个defer函数最后一个被执行。正如上述例3代码中第三个defer函数先执行,然后再是第二个defer函数执行,最后再是第一个defer函数执行
type _defer struct{sp uintptr //函数栈指针pc uintptr //程序计数器fn *funcval //函数地址lnk *_defer //指向自身结构的指针,用于链接多个defer
}
package mainimport "fmt"func df()int{i:=5defer func(){i = i + 10}()return i
}
func main(){ri := df()fmt.Println(ri)
}
package mainimport "fmt"func df()int{i:=5defer func(){i = i + 10fmt.Println("defer函数中的i:",i)}()fmt.Println("df中的i:",i)return i
}
func main(){ri := df()fmt.Println(ri)
}
结果:
package mainimport "fmt"func df()(i int){i = 5defer func(){i = i + 10fmt.Println("defer函数中的i:",i)}()fmt.Println("df中的i:",i)return i
}
func main(){ri := df()fmt.Println(ri)
}
结果:
package mainimport "fmt"func main(){panic("aaaaa")defer func(){fmt.Println("执行defer")}()
}
结果:package mainimport "fmt"func main(){defer func(){fmt.Println("执行defer")}()panic("aaaaa")
}
结果: