一、函数可赋值给一个变量
示例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() // 其他代码 }