函数

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还支持匿名函数,匿名函数经常在defergo关键字后面看到。

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 }