定义
语法 - func 函数名 (参数列表) (返回值列表){
}
package main import ( "fmt" ) func myfunc(a, b int) (r1, r2 int) { r1 = a + b r2 = a - b return } func main() { r1, r2 := myfunc(5, 1) fmt.Println(r1) fmt.Println(r2) }
//output
6
4
匿名函数
Go 语言允许将函数传递给一个变量,即定义函数也算是定义一种类型。 声明匿名函数时,可以省略函数的名称
func main() { f1 := func() { fmt.Println("I am fuction 1...") } f1() } //output I am fuction 1...
闭包
func closure(x int) func(y int) (r int) { fmt.Printf("%p ", &x) return func(y int) (r int) { fmt.Printf("%p ", &x) r = x + y return r } } func main() { f2 := closure(10) fmt.Println(f2(1)) fmt.Println(f2(2)) } //output 0x114821dc 0x114821dc 11 0x114821dc 12
defer
Go 函数通过使用defer关键字,实现了许多“神奇”的事情
1. 改变函数执行的顺序 - 如果在函数体中定义 defer, 会按照与定义顺序相反的顺序执行
func main() { for i := 0; i < 3; i++ { defer fmt.Println(i) } } //output 2 1 0
2. Go语言没有异常处理(try...catch),但可以使用 “panic + recover” 模式来处理异常. panic可以在任何地方触发,但是recover必须在defer调用的函数中执行,且必须定义在panic之前
func A() { fmt.Println("function A ...") } func B() { defer func() { if err := recover(); err != nil { fmt.Println("recover") } }() panic("panic in function B") } func C() { fmt.Println("function C ...") } func main() { A() B() C() } //output function A ... recover function C ...
所以: 通过使用defer + recover 的方式,可以达到 “finally”的效果,例如清理资源,关闭文件等。