zoukankan      html  css  js  c++  java
  • 【原创】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)
    }
    

      

  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/wangshuyang/p/11761909.html
Copyright © 2011-2022 走看看