• 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()
    	// 其他代码
    }
    
  • 相关阅读:
    struts2上传下载
    git教程
    mysql触发器2
    mysql触发器
    mysql set sql_mode 1055 报错
    一些乱七八糟的话
    linux 命令2
    linux命令 mysql
    东南亚之行(越南篇)
    flume常见配置
  • 原文地址:https://www.cnblogs.com/believepd/p/10853928.html
Copyright © 2020-2023  润新知