Go-闭包和匿名函数讲解

回调函数及多态

 1 package main
 2 
 3 import "fmt"
 4 
 5 //给匿名函数类型取别名
 6 //注意不要在后面加{},加了是表面匿名函数定义
 7 type FuncType func(x int, y int) int
 8 
 9 //例如实现加法
10 func Add(x int, y int) int {
11     val := x + y
12     return val
13 }
14 
15 //例如实现减法
16 func Sub(x int, y int) int {
17     val := x - y
18     return val
19 }
20 
21 //例如实现乘法
22 func Mul(x int, y int) int {
23     val := x * y
24     return val
25 }
26 
27 //例如实现除法
28 func Div(x int, y int) int {
29     val := x / y
30     return val
31 }
32 
33 //回调函数,函数有一个参数是函数类型, 这个函数就是回调函数
34 //多态,多种形态,调用同一个接口,不同的表现,可以实现不同表现,例如:加减乘除
35 //先有想法,后面再实现功能
36 func callback(a, b int, fTest FuncType) int {
37     fmt.Println("这个个回调函数")
38     res := fTest(a, b) //这个函数还没有实现
39     //result := Add(a, b) //这样不好,因为Add()必须先定义后,才能调用,而且会写死这个callback函数功能
40     return res
41 }
42 
43 func main() {
44     val := callback(1, 1, Add)
45     fmt.Println("val=", val)
46     val = callback(1, 1, Sub)
47     fmt.Println("val=", val)
48     val = callback(1, 1, Mul)
49     fmt.Println("val=", val)
50     val = callback(1, 1, Div)
51     fmt.Println("val=", val)
52 }
View Code

 

闭包:

  一个函数捕获了和它在同一作用域的其它常量和变量。

匿名函数和闭包  

 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6     a := 10
 7     s := "test"
 8 
 9     //匿名函数,没有函数名,这个是匿名函数的定义,还没有调用
10     f := func() {
11         fmt.Println("a=", a)
12         fmt.Println("s=", s)
13     }
14     f()
15     //给一个函数类型起别名
16     type FuncType func() //函数没有参数,没有返回值
17     //声明变量
18     // f1 := f
19     var f1 FuncType
20     f1 = f
21     f1()
22 
23     //需求:定义匿名函数,同时调用
24     func() {
25         fmt.Println("定义匿名函数,同时调用")
26     }() //后面的()代表调用此匿名函数
27 
28     //需求:带参数的匿名函数
29     f2 := func(i, j int) {
30         fmt.Printf("i=%d, j=%d\n", i, j)
31     }
32     f2(1, 2)
33 
34     func(i, j int) {
35         fmt.Printf("i=%d, j=%d\n", i, j)
36     }(10, 20)
37 
38     //需求:匿名函数,带参数带返回值
39     x, y := func(a, b int) (max, min int) {
40         if a > b {
41             max = a
42             min = b
43         } else {
44             max = b
45             min = a
46         }
47         return
48     }(2, 4)
49     fmt.Printf("x=%d, y=%d", x, y)
50 }
View Code

 

闭包捕获外部变量的特点

 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {
 6     //闭包以引用方式捕获外部变量
 7     a := 10
 8     str := "mike"
 9     func() {
10         a = 666
11         str = "Paul"
12         fmt.Printf("内部: a=%d, str=%s\n", a, str)
13     }() //()代表直接调用
14     fmt.Printf("外部:a=%d, str=%s\n", a, str)
15 }
View Code

 

闭包调用局部变量,与普通调用函数时局部变量的区别

 1 package main
 2 
 3 import "fmt"
 4 
 5 func test() func() int {
 6     var x int
 7 
 8     return func() int {
 9         x++
10         return x * x // 闭包,调用了局部变量x
11     }
12 }
13 func main() {
14     f := test()
15     //闭包用到这些局部变量,局部变量生命周期不由它的作用域决定
16     //只有闭包还在使用它,这些局部变量就还会存在
17     fmt.Println(f()) //1
18     fmt.Println(f()) //4
19     fmt.Println(f()) //9
20     fmt.Println(f()) //16
21     fmt.Println(f()) //25
22 }
23 
24 func test01() int {
25     var x int //局部变量
26     x++
27     return x * x // 函数调用完毕,x自动释放
28 }
29 
30 func main01() {
31     fmt.Println(test01()) //1
32     fmt.Println(test01()) //1
33     fmt.Println(test01()) //1
34     fmt.Println(test01()) //1
35 }
View Code

 

posted @ 2019-05-11 15:32  大西瓜Paul  阅读(260)  评论(0编辑  收藏  举报
/*增加返回顶部按钮*/ 返回顶部 /*给标题增加蓝色背景长条*/