闭包 / Defer / Error
Google开发专家带你学 AI:入门到实战(Keras/Tensorflow)(附源码)
闭包
介绍
基本介绍: 闭包就是一个函数和与其相关的引用环境组成的一个整体(实体)
案例演示
// 闭包的测试
func AddUpper() func( int ) int {
var n int = 10 ;
return func(i int) int {
n = n + i
return n
}
}
func main() {
// 闭包的测试
addUpper := function.AddUpper()
fmt.Println(addUpper(1))
fmt.Println(addUpper(2))
}
说明
- AddUpper() 是一个函数,返回的数据类型是 func(int) int .
- 闭包的说明: 返回的是一个函数,入演示中的匿名函数,但是这个匿名函数引用到了函数外的资源 n , 因此,匿名函数和 n 形成一个整体,从而构成一个闭包。
- 可以这么理解: 闭包是一个类,这个函数是方法, n 是变量。
- 当我们反复调用 addUpper 时,n 是初始化一次,构成了累加。
- 闭包的关键在于 返回的函数引用到了哪些变量?
Defer的理解
介绍
在函数中,程序员经常需要创建资源(比如:数据库连接、文件句柄、锁等) ,为了在 函数执行完毕后,及时的释放资源,Go 的设计者提供 defer (延时机制)。
案例演示
func Sum(x , y int) int{
// 当执行到 defer 时,会将当前的语句压入到 defer 的独立的栈中,暂时不会去执行
defer fmt.Println("x = " , x)
// 当当前函数执行结束后,在从 defer 栈中先入后出的原则去执行
defer fmt.Println("y = " , y)
res := x + y
fmt.Println("res = " , res)
return res
}
func main() {
sum := function.Sum(10, 20)
fmt.Println("sum = " , sum)
}
执行的结果如下:
res = 30
y = 20
x = 10
sum = 30
Defer的价值 当函数执行完毕后,可以及时的释放函数创建的资源
GO 中的错误的处理方式
演示案例
func ErrorTest(){
num1 := 10
num2 := 0
res := num1 / num2
fmt.Println(res)
}
执行的结果如下:
panic: runtime error: integer divide by zero
goroutine 1 [running]:
go-learn/src/function.ErrorTest()
D:/Projects/GoProjects/go-learn/src/function/error.go:13 +0x11
main.main()
D:/Projects/GoProjects/go-learn/main.go:11 +0x27
对于异常,的处理方案如下:
- 使用 defer + recover 来捕获异常并处理
func ErrorTest(){
defer func() {
err := recover()
if err != nil {
fmt.Println("err = " , err)
}
}()
num1 := 10
num2 := 0
res := num1 / num2
fmt.Println(res)
}
自定义错误
Go 中,可以对错误进行自定义,一般使用 errors.New("") / panic(""
)