1.定义函数类型
package main
import "fmt"
type addFunc func(a, b int) int
func operate(f addFunc, a, b int) int {
return f(a, b)
}
func add(a, b int) int {
return a + b
}
func add2(a, b int) int {
return a + b + b + a
}
func main() {
c := operate(add2, 1, 2)
c2 := operate(add, 1, 2)
fmt.Println(c)
fmt.Println(c2)
}
2.defer语句
延迟调用函数,只能用于函数内部
func outerFunc() {
defer fmt.Println("函数执行结束前一刻才会被打印")
fmt.Println("第一个被打印")
}
将outerFunc称为外围函数,调用outerFunc的位调用函数
执行规则
a.当外围函数正常语句执行完毕时 ,只有其中所有的延迟函数执行完毕,外围函数才会真正地结束执行
b.当执行外围函数中的return语句时,只有所有的延迟函数执行完毕1,外围函数才会真正返回
c.当外围函数中的代码引发运行恐慌时,只有其中所有的延迟函数都执行完毕后,该运行时恐慌才会真正被扩散至调用函数
执行释放资源或异常处理收尾工作
位置不限 数量不限
注意事项
a.如果在延迟函数中使用外部变量,应该通过参数传入
b.同一个外围函数内含多个延迟函数的执行顺序,与defer顺序完全相反
c.延迟函数调用若有参数传入,那么那些参数的值会在当前defer语句执行时求出
func testNum() {
for i := 0; i < 5; i++ {
defer func(n int) {
println(n)
}(i * 2)
}
}
/*打印结果
8
6
4
2
0
*/
3.panic
panic函数用于停止当前控制流程并引发一个运行时恐慌
参数类型大多数是string或者error类型
func panicTest() {
i := []int{1, 2, 3}
println(i[4])//索引越界
}
/*
* 显示调用panic函数并传入一个 runtime.Error类型的参数值
* panic: runtime error: index out of range [4] with length 3
*/
4.recover
拦截运行时恐慌的内建函数,可以使程序从恐慌中恢复并且重新获得流程的控制权。
recover函数返回interface{},当程序正处于运行时恐慌的状态,那么这个结果就是非nil的。
recover函数应该与defer语句配合使用
func panicTest() {
//放在函数体的开始处
defer func() {
if p := recover(); p != nil {
fmt.Println("Revover panic:%s\n", p)
}
}()
i := []int{1, 2, 3}
println(i[4])
println(i[2])
}
/*
* Revover panic:%s
*runtime error: index out of range [4] with length 3
/
作用:
a.可以把运行时间恐慌的携带值转换为error类型值,并当做常规结果放会给调用方。阻止恐慌的扩散,传递恐慌原因
b.根据运行时恐慌携带值的类型,根据类型做不同的后续动作,精确控制程序错误处理行为