go中的函数不支持嵌套,重载,默认参数
函数可以结构多个变量,多个变量整合放在最后面,返回值可以定义其行参,如果定义,直接return隐式返回,如果不定义,则需要指明返回的数据,显示返回,在本例中 return z
func sum(x, y int, opt ...int) (z int) { z = x + y for _, i := range (opt) { z += i } return } func main() { fmt.Println(sum(1,2)) // 3 fmt.Println(sum(1,2, 3,4,5,6)) // 21 }
另外对于多值返回的,必须用多值接受,如果不想要,可以使用_忽略
func sum(x, y int, opt ...int) (m, n int) { m = x + 1 n = y + 1 return } func main() { a, b := sum(1,2) fmt.Println(sum(a, b)) c, _ := sum(1,2) fmt.Println(c) }
go 中也有匿名函数
func main() { lambda := func(m int) {fmt.Println("i am lambda", m )} lambda(1) }
延期调用 defer,这是一个很实用的功能,当函数执行完毕后后,会调用defer,一个函数可以注册多个defer,遵循原则FILO(first in last out),就算其中一个执行错误,也会继续执行
func main() {
var x int
fmt.Println("start")
time.Sleep( time.Second * 2)
defer fmt.Println("first")
defer func(x int){fmt.Println(100/x)}(x)
defer fmt.Println("third")
fmt.Println("i am over")
}
start
i am over
third
first
panic: runtime error: integer divide by zero
defer不要滥用,否则会影响性能
错误处理
一般用panic抛出异常,recover捕捉错误
捕捉函数只有在延期调用内直接调用才会终止错误,否则捕捉不到错误,如果存在未被捕捉的错误,会向外传递
func test() { defer recover() // 这个无法捕捉,未再内部调用 defer fmt.Println(recover()) // 同理 defer func() { func() { fmt.Println("defer inner") recover() // 多加了一层,仍然捕捉不到错误 }() }() panic("test panic") // 抛出错误 } func main() { test() }
这样就可以捕捉到错误
func test() { defer func() { fmt.Println("defer inner") fmt.Println(recover()) }() panic("test panic") } func main() { test() }
对于一般错误建议通过error方式进行返回, 调用errors的New方法新建一个错误
func test(x int) (int, error) { if x > 10 { return x, nil } else { return x, errors.New("参数过小") } } func main() { x, err := test(1) x2, _ := test(11) fmt.Println(x, x2, err) }