函数
golang的函数有很多独特的创新。比如golang的函数支持多个返回值,而且支持返回值命名,golang的函数中支持defer
。
go函数声明格式
func 函数名(参数列表) (返回值列表) {
//函数体
}
在参数列表中,多个相同类型可简写如下
func add1(a int,b int) int {
return a+b
}
//参数列表可简写
func add2(a,b int) int {
return a+b
}
golang支持函数有多个返回值。如果函数只有一个返回值可以简写成如下格式
func 函数名(参数列表) 返回值 {
//函数体
}
golang还支持命名的返回值。
func read(url string) (string,error) {
content, err := 函数类型的零值是nil。调用值为nil的函数值会引起pani
return string(content),nil
}
//只返回一个返回值
func add(a int,b int) int {
return a+b
}
//无返回值
func swap(a *int,b *int) {
temp := *a
*a = *b
*b = temp
}
//命名的返回值
func add(a int,b int)(c int) {
c = a+b
return
}
函数类型
在golang中定义的函数可以被看做一种值类型,可以赋值给函数类型变量。函数类型的默认初始值为nil。
func add(a int,b int) int {
return a+b
}
fn := add //fn的类型为 func(a,b int)
fmt.Println(f(1,2))
可变参数
golang支持可变参数,但是要求参数类型是一致的。其实golang的可变参数是一个slice
。
可变参数在fmt
包中非常常见。比如Printf
定义为func Printf(format string, a ...interface{}) (n int, err error)
。
由于使用了interface{}
接口类型,所以它可以接收任意类型参数。
func sum(arr ...int) int {
totalNum := 0
for _, v := range arr {
totalNum += v
}
return totalNum
}
defer
golang中defer
关键字运行我们推迟到函数返回之前执行代码块或函数。defer
通常被设计来关闭资源或者处理panic
。一个函数中支持有多个defer,
多个defer的执行顺序为代码位置逆序。
func ReadFile(filename string) ([]byte, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
return ReadAll(f)
}
匿名函数
golang还支持匿名函数,匿名函数经常在defer
和go
关键字后面看到。
func ReadFile(filename string) ([]byte, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer func() { //匿名函数
f.Close()
//再做点其他事情
}()
return ReadAll(f)
}
go func(){ //开启一个go协程
//做点事情
}()
函数递归
golang的函数也支持递归,如下我们用递归的方式实现斐波那契数列。
func fibonacci(n int) (res int) {
if n <= 1 {
res = 1
} else {
res = fibonacci(n-1) + fibonacci(n-2)
}
return
}