函数 func
一、函数声明
- 函数名称
- 形参列表
- 返回列表
- 函数体
-
形参列表
指定了一组变量的参数名和参数类型,属于局部变量,由调用者提供的**实参*(按值传递)***传递而来
-
返回列表
指定了函数的返回值,可以为空
当存在返回值时,必须显式声明
returnfunc hypot(x, y float64) float64 { return math.Sqrt(x * x + y * y) } func f(i, j, k int, s, t string) {/* ... */} func f(i int, j int, k int, s string, t string) {/* ... */}
函数签名
函数的类型,e.g.
func(int, int) int参数传递
- 函数形参以及命名返回值同属于函数最外层作用于的局部变量
- 当实参列表不包含引用类型(e.g.指针、slice、map、函数或通道)修改函数本身不会影响带调用者提供的实参
汇编函数
无返回体
e.g.
package math func Sin(x float64) float64
二、递归
golang中函数可以递归调用,即函数可以直接或间接地调用自身
三、错误处理
-
通用策略
将错误传递下去,使在子例程序中的错误传递到主调程序中的错误,并抛出错误
-
重复策略
对于不固定或者不可预测的错误,在短暂的隔离后进行重试,超出一定重试次数或限制时间后,抛出错误
-
恐慌策略
抛出错误并引发程序恐慌
四、函数变量
-
函数类型的零值为
nil,会引发程序恐慌从而发生宕机 -
函数本身不可以比较,但是函数变量可以使数据进行参数化,也可以将函数的行为作为参数传递
e.g.
func add1(r rune) rune { return r + 1 } fmt.Println(strings.Map(add1, "HAL-9000")) fmt Println(strings.Map(add1, "VMS")) fmt.Println(strings.Map(add1, "Admix"))闭包
即函数变量
五、匿名函数
在func关键字吼main没有函数名称,类型为表达式,表达式的值称为匿名函数
e.g.
// func squares() renturn other func, type is `func() int`
func squares() func() int {
var x int
return func() int {
x++
return x
}
}
六、延长函数
没有固定长度的形参列表
e.g.
func sum (vals ...int) int {
count := 0
for _, val := range vals {
count += val
}
return count
}
fmt.Println(func(1))
fmt.Println(func(1, 2))
fmt.Println(func(1, 2, 3, 4))
七、延迟函数
defer函数生效后,return语句或panic语句才会生效defer函数可以无限次调用- 当存在多个
defer函数时,倒序调用defer函数