一、函数可赋值给一个变量
示例1:
package mainimport "fmt"func add(a, b int) int { return a + b}func main() { xx := add fmt.Println(xx(10, 10)) // 20}
示例2:
package mainimport "fmt"// opFunc为自定义的类型名字,这里它是一个函数,接收两个值,返回一个值type opFunc func(int, int) intfunc 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 mainimport "fmt"// opFunc为自定义的类型名字,这里它是一个函数,接收两个值,返回一个值//type opFunc func(int, int) intfunc 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 mainimport "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 mainimport "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 mainimport "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 mainimport "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 mainimport "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 mainimport "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() // 其他代码}