• 【原创】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
    ", f1)
    	sum := f1(2, 5)
    	fmt.Printf("sum=%d
    ", sum)
    }
    

      

    2、匿名函数,即没有名字的函数

    //匿名函数
    func testFunc2() {
    	f1 := func(a, b int) int {
    		return a + b
    	}
    	// %T 函数类型
    	fmt.Printf("typeof f1=%T
    ", f1)
    	sum := f1(2, 5)
    	fmt.Printf("sum=%d
    ", sum)
    
    }
    

      

    3、defer中使用匿名函数

    // defer应用
    func testFunc3() {
    	var i int = 0
    	// 最后输出
    	defer fmt.Printf("defer i=%d
    ", i)
    	i = 100
    	fmt.Printf("i=%d", i)
    	return
    }
    

      

    //defer + 匿名函数= 闭包
    func testFunc4() {
    	var i int = 0
    	// 最后输出+匿名函数
    	defer func() {
    		fmt.Printf("defer i=%d
    ", 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
    ", 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 ", ret)
    ret = f(20)
    fmt.Printf("ret=%d ", ret)
    ret = f(100)
    fmt.Printf("ret=%d ", ret)

    // 从0加起
    f1 := Adder()
    ret = f1(1)
    fmt.Printf("ret=%d ", ret)
    ret = f1(20)
    fmt.Printf("ret=%d ", ret)
    ret = f1(100)
    fmt.Printf("ret=%d ", 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)
    }
    

      

  • 相关阅读:
    java 字符串split有很多坑,使用时请小心!!
    Java并发编程:线程池的使用
    java自带线程池和队列详细讲解
    merge into的用法
    Oracle中如何使用REGEXP_SUBSTR函数
    oracle分组统计某列逗号隔开数据
    oracle一列中的数据有多个手机号码用逗号隔开,我如何分别取出来?
    css box-shadow使用---转
    201706问题记录
    201705问题记录
  • 原文地址:https://www.cnblogs.com/wangshuyang/p/11761909.html
Copyright © 2020-2023  润新知