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()
// 其他代码
}

浙公网安备 33010602011771号