函数
定义
可以给返回值命名,就像函数的输入参数一样。返回值被命名之后,它们的值在函数开始的时候被自动初始化为空。在函数中执行不带任何参数的return语句时,会返回对应的返回值变量的值
package mymath
import "errors"
func Add(a int, b int) (ret int, err error) {
if a < 0 || b < 0 { // 假设这个函数只支持两个非负数字的加法
err = errors.New("Should be non-negative numbers!")
return // 默认返回ret, err
}
return a + b, nil // 支持多重返回值
}
fun Add2(a, b int) (ret int, err error) {
//参数类型相同时
}
fun Add3(a, b int) int {
//返回值只有一个时
}
不定参数
func myfunc(args ...int) {
for _, arg := rangeargs {
fmt.Println(arg)
}
}
myfunc(2, 3, 4)
ls := []int{1, 2, 3}
mufunc(ls...)
匿名函数:
f := func(x, y int) int{
returnx + y
}
func(ch chan int) {
ch <- ACK
} (reply_chan) // 花括号后直接跟参数列表表示函数调用
错误处理
Go语言引入了一个关于错误处理的标准模式,即error接口:
type error interface{
Error() string
}
对于大多数函数,如果要返回错误,大致上都可以定义为如下模式,将error作为多种返回值中的最后一个,但这并非是强制要求: func Foo(param int)(n int, err error) { // ... }
调用时的代码建议按如下方式处理错误情况:
n, err := Foo(0)
if err != nil {
// 错误处理
} else{
// 使用返回值n
}
自定义错误:
type PathError struct {
Op string
Path string
Err error
}
func(e *PathError) Error() string{
returne.Op + " " + e.Path + ": " + e.Err.Error()
}
defer
defer提供了优雅的退出前清扫机制:
func CopyFile(dst, src string) (w int64, err error) {
src File, err := os.Open(src)
if err != nil{
return
}
defer srcFile.Close()
dst File, err := os.Create(dstName)
if err != nil{
return
}
defer dstFile.Close()
return io.Copy(dstFile, srcFile)
}
还可以使用匿名函数:
defer func(){
//
}()
异常处理
Go语言引入了两个内置函数panic()和recover()以报告和处理运行时错误和程序中的错误场景:
func panic(interface{})
func recover() interface{}
当在一个函数执行过程中调用panic()函数时,正常的函数执行流程将立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐层向上执行panic流程,直至所属的goroutine中所有正在执行的函数被终止。错误信息将被报告,包括在调用panic()函数时传入的参数,这个过程称为错误处理流程。
recover()函数用于终止错误处理流程。一般情况下,recover()应该在一个使用defer关键字的函数中执行以有效截取错误处理流程。如果没有在发生异常的goroutine中明确调用恢复过程(使用recover关键字),会导致该goroutine所属的进程打印异常信息后直接退出。
package main
import "fmt"
func main() {
defer func() {
if r := recover(); r != nil{
fmt.Printf("Runtime error caught: %v", r)
}
}()
func(){
panic("test")
fmt.Println("ok")
}()
}
上面的代码,匿名函数调用了panic, 导致改函数流程结束,但是因为defer了一个处理函数,输出不会看到panic抛出的异常信息,而是recover打印的信息。:
Runtime error caught: test