【原创】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)
}

  

posted @ 2019-10-29 22:07  shuyang  阅读(274)  评论(0编辑  收藏  举报