zoukankan      html  css  js  c++  java
  • Go:函数、defer

    一、函数可赋值给一个变量

    示例1:

    package main
    
    import "fmt"
    
    func add(a, b int) int {
    	return a + b
    }
    
    func main() {
    	xx := add
    	fmt.Println(xx(10, 10)) // 20
    }
    

    示例2:

    package main
    
    import "fmt"
    
    // opFunc为自定义的类型名字,这里它是一个函数,接收两个值,返回一个值
    type opFunc func(int, int) int
    
    func add(a, b int) int {
    	return a + b
    }
    
    // op为变量名字,op_func为自己定义的类型
    func operator(op opFunc, a, b int) int {
    	return op(a, b)
    }
    
    func main() {
    	xx := add
    	result := operator(xx, 10, 10)
    	fmt.Println(result) // 20
    }
    

    示例3:示例2也可以写成如下,示例2中为什么使用type自定义类型?这样可以让函数没那么繁琐,更简洁。

    package main
    
    import "fmt"
    
    // opFunc为自定义的类型名字,这里它是一个函数,接收两个值,返回一个值
    //type opFunc func(int, int) int
    
    func add(a, b int) int {
    	return a + b
    }
    
    // op为变量名字,op_func为自己定义的类型
    func operator(op func(int, int) int, a, b int) int {
    	return op(a, b)
    }
    
    func main() {
    	xx := add
    	result := operator(xx, 10, 10)
    	fmt.Println(result) // 20
    } 

    二、可变参数

    // 0个或多个参数
    func sumArgs(args …int) int {
    }
    // 1个或多个参数
    func sumArgs(a int, args …int) int {
    }
    // 2个或多个参数
    func sumArgs(a int, b int, args …int) int {
    }

    注意:其中args是一个slice,我们可以通过args[index]依次访问所有参数,通过len(args)来判断传递参数的个数。

    示例:

    package main
    
    import "fmt"
    
    func sumArgs(args ...int) int {
    	sum := 0
    	for i := range args {
    		sum += args[i]
    	}
    	return sum
    }
    
    func main() {
    	fmt.Println(sumArgs(1, 2, 3, 4, 5)) // 15
    }
    

    三、匿名函数

    package main
    
    import "fmt"
    
    func add(a, b int) int {
    	result := func(a1, b1 int) int {
    		return a1 + b1
    	}(a, b) // 定义时就调用
    	return result
    }
    
    func main() {
    	fmt.Println(add(10, 10)) // 20
    }
    

    或者:

    package main
    
    import "fmt"
    
    func add(a, b int) int {
    	result := func(a1, b1 int) int {
    		return a1 + b1
    	}
    	return result(a, b)
    }
    
    func main() {
    	fmt.Println(add(10, 10)) // 20
    }
    

    全局匿名函数:

    package main
    
    import "fmt"
    
    var (
    	//Func就是一个全局匿名函数
    	Func = func(a, b int) int {
    		return a * b
    	}
    )
    
    func main() {
    	result := Func(10, 10)
    	fmt.Println(result)
    }

    四、defer用途

    • 当函数返回时,执行defer语句,因此,可以用来做资源清理;
    • 多个defer语句,按先进后出的方式执行;
    • defer语句中的变量,在defer声明时就决定了。

    示例:

    package main
    
    import "fmt"
    
    func test(a, b int) {
    	defer fmt.Println(a)
    	defer fmt.Println(b)
    	tmp := a + b
    	fmt.Println(tmp)
    }
    
    func main() {
    	test(10, 20)
    }
    
    // 输出结果:
    // 30
    // 20
    // 10
    

    在 defer 将语句代码放入到栈时,也会将相关的值拷贝同时入栈:

    package main
    
    import "fmt"
    
    func test(a, b int) {
    	defer fmt.Println(a)
    	defer fmt.Println(b)
    	a++
    	b++
    	tmp := a + b
    	fmt.Println(tmp)
    }
    
    func main() {
    	test(10, 20)
    }
    
    // 输出结果:
    // 32
    // 20
    // 10
    

    defer的最主要价值是,当函数执行完毕后,可以及时的释放函数创建的资源(请看如下伪代码):

    func test() {
    	// 关闭文件资源
    	file = openFile(文件名)
    	defer file.close()
    	// 其他代码
    }
    
    func test() {
    	// 释放数据库支援
    	conn = openDatabase()
    	defer conn.close()
    	// 其他代码
    }
    
  • 相关阅读:
    单调队列 POJ 2823
    大组合数取mod lucas 定理
    多校4
    多校2
    2016多校1
    百度之星 初赛B续
    iot-web增加apis-namespace组件
    25.75k8s
    新项目增加gradlew
    vue图片点击放大预览v-viewer
  • 原文地址:https://www.cnblogs.com/believepd/p/10853928.html
Copyright © 2011-2022 走看看