【原创】go语言学习(六)函数详解2
目录
- 变量作用域和可见性
- 匿名函数
- 闭包
- 课后练习
变量作用域和可见性
1、全局变量量,在程序整个生命周期有效。
var a int = 10
2、局部变量量,分为两种:
1)函数内定义,
2)语句句块内定义。
func add(a int, b int) int { var sum int = 0 //sum是局部变量量 if a > 0 { var c int = 100 //c是布局变量量,尽在if语句句块有效 } }
3. 可⻅见性,包内任何变量量或函数都是能访问的。
包外的话,⾸首字⺟母⼤大写是可导出的 能够被其他包访问或调⽤用。
小写表示是私有的,不不能被外部的包访问。
func add(a int, b int) int { } //add这个函数只能在包内部调⽤用,是私有的,不不能被外部的包调
匿名函数
1、函数也是一种类型,因此可以定义一个函数类型的变量
func add(a, b int) int { return a + b } func testFunc1() { f1 := add // %T 函数类型 fmt.Printf("typeof f1=%T\n", f1) sum := f1(2, 5) fmt.Printf("sum=%d\n", sum) }
2、匿名函数,即没有名字的函数
//匿名函数 func testFunc2() { f1 := func(a, b int) int { return a + b } // %T 函数类型 fmt.Printf("typeof f1=%T\n", f1) sum := f1(2, 5) fmt.Printf("sum=%d\n", sum) }
3、defer中使用匿名函数
// defer应用 func testFunc3() { var i int = 0 // 最后输出 defer fmt.Printf("defer i=%d\n", i) i = 100 fmt.Printf("i=%d", i) return }
//defer + 匿名函数= 闭包 func testFunc4() { var i int = 0 // 最后输出+匿名函数 defer func() { fmt.Printf("defer i=%d\n", i) }() i = 100 fmt.Printf("i=%d", i) return }
4、函数作为一个参数
// 函数作为参数 func add_1(a, b int) int { return a + b } func sub(a, b int) int { return a - b } func calc(a, b int, op func(int, int) int) int { return op(a, b) } func testFunc5() { sum := calc(100, 300, add_1) sub := calc(100, 300, sub) fmt.Printf("sum=%d sub=%d\n", sum, sub) }
闭包
1、闭包:一个函数和与其相关的引⽤用环境组合⽽而成的实体
// 闭包 func Adder() func(int) int { var x int //闭包 return func(d int) int { x += d return x } }
func testClosure1() {
// 闭包累加
f := Adder()
ret := f(1)
fmt.Printf("ret=%d\n", ret)
ret = f(20)
fmt.Printf("ret=%d\n", ret)
ret = f(100)
fmt.Printf("ret=%d\n", ret)
// 从0加起
f1 := Adder()
ret = f1(1)
fmt.Printf("ret=%d\n", ret)
ret = f1(20)
fmt.Printf("ret=%d\n", ret)
ret = f1(100)
fmt.Printf("ret=%d\n", ret)
}
2、带参数的闭包
// 带参数闭包 func add(base int) func(int) int { return func(i int) int { base += i return base } } func testClosure2() { tmp1 := add(10) fmt.Println(tmp1(1), tmp1(2)) tmp2 := add(100) fmt.Println(tmp2(1), tmp2(2)) }
3、test.bmp, test.jpg 参数闭包
// test.bmp, test.jpg 参数闭包 func makeSufficxFunc(suffix string) func(string) string { return func(name string) string { if !strings.HasPrefix(name, suffix) { return name + suffix } return name } } func testClosure3() { func1 := makeSufficxFunc(".bmp") func2 := makeSufficxFunc(".jpg") fmt.Println(func1("test")) fmt.Println(func2("test")) }
4、返回两个闭包
func calc(base int) (func(int) int, func(int) int) { add := func(i int) int { base += i return base } sub := func(i int) int { base -= i return base } return add, sub } func testClosure4() { f1, f2 := calc(10) fmt.Println(f1(1), f2(2)) fmt.Println(f1(3), f2(4)) fmt.Println(f1(5), f2(6)) fmt.Println(f1(7), f2(8)) }
5、需要参数,不然封装的结果都是5
func testClosure5() { //for i:=0; i< 5; i++ { // go func(){ // fmt.Println(i) // }() //} //time.Sleep(time.Second) for i := 0; i < 5; i++ { go func(index int) { fmt.Println(index) }(i) } time.Sleep(time.Second) }