函数是指一段可以直接被另一段程序或代码引用的程序或代码。也叫做子程序、(OOP中)方法。 一个较大的程序一般应分为若干个程序块,每一个模块用来实现一个特定的功能。所有的高级语言中都有子程序这个概念,用子程序实现模块的功能。在C语言中,子程序的作用是由一个主函数和若干个函数构成。由主函数调用其他函数,其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。

在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用。要善于利用函数,以减少重复编写程序段的工作量。


一、函数的概念

函数(funcation)是一段组织好的,用来完成特定功能的代码块,也叫做子程序。要善于使用函数,其可以提高应用的模块性和代码的复用率。

二、Go语言函数

Go 语言支持普通函数、匿名函数和闭包,从设计上对函数进行了优化和改进,让函数使用起来更加方便。
Go 语言的函数属于“一等公民”(first-class),也就是说:

  • 函数本身可以作为值进行传递。
  • 支持匿名函数和闭包(closure)。
  • 函数可以满足接口。

函数定义

和Python/Js等语言定义函数方式一样,Go语言使用func关键字来定义一个函数。

  1. func funcationName(parameter-list) returnValue-Type {
  2. //func body...
  3. }

实例

  1. package main
  2. import "fmt"
  3. //函数名在前,返回值类型在后 ,参数列表也一样 变量名在前 ,类型在后
  4. func calc(x,y int,op string) int {
  5. switch op {
  6. case "+":
  7. return x+y
  8. case "-":
  9. return x-y
  10. case "*":
  11. return x*y
  12. case "/":
  13. return x/y
  14. default:
  15. panic("unsupportted operation :"+ op)?//报错,中断执行
  16. }
  17. }
  18. func main() {
  19. fmt.Println(calc(3,5,"+"))
  20. }

和C语言函数一样,Go语言函数的参数和返回值类型都是可选的,无参数和返回值类型例子如下:

  1. func sayHello() {
  2. fmt.Println("Hello 沙河")
  3. }

返回值

多返回值函数

Go语言函数支持多个返回值,函数如果有多个返回值时必须用()将所有返回值包裹起来。

  1. //带余除法函数,函数返回多个值
  2. func calc2(x,y int) (int int) {
  3. q =x/y
  4. r =x%y
  5. return x/y,x%y
  6. }
  7. func main() {
  8. fmt.Println(calc1(13,3))
  9. }

返回值命名

在定义多个返回值的Go语言函数,为了区分可以在定义函数时给返回值命名,并且在函数体中直接使用这些变量,最后通过return关键字返回

  1. //带余除法函数,函数返回多个值
  2. func calc2(x,y int) (q,r int) {
  3. q =x/y
  4. r =x%y
  5. return q,r
  6. }
  7. func main() {
  8. q,r:=calc2(13,3)// 13/3=4...1
  9. fmt.Println(q,r)
  10. }

Go语言支持多返回值,多返回值能方便地获得函数执行后的多个返回参数,Go语言经常使用多返回值中的最后一个返回参数error返回函数执行中可能发生的错误,示例代码如下:

  1. //函数名在前,返回值类型在后 ,参数列表也一样 变量名在前 ,类型在后
  2. func calc(x,y int,op string) (result int,err error) {
  3. switch op {
  4. case "+":
  5. return x+y,nil
  6. case "-":
  7. return x-y,nil
  8. case "*":
  9. return x*y,nil
  10. case "/":
  11. return x/y,nil
  12. default:
  13. return 0,fmt.Errorf("unsupportted operation : %s",op)
  14. }
  15. }
  16. //adder函数, 返回值类型是func() int
  17. func adder() func() int{
  18. var x int=3
  19. return func() int {
  20. return x*x //访问外层函数的局部变量
  21. }
  22. }
  23. func main() {
  24. //fmt.Println(calc(13,3 ,"/"))
  25. if result,err:=calc(13,3,"/"); err != nil {
  26. fmt.Println("error:",err)
  27. }else{
  28. fmt.Println("result:",result)
  29. }
  30. var result func() int =adder()
  31. fmt.Println(result())
  32. }

匿名函数

匿名函数和闭包

和JavaScript一样,Go语言也有匿名函数,但是Go语言只允许在一个函数中使用一个匿名函数

  1. func (参数列表) 返回值类型{
  2. 函数体
  3. }

因为匿名函数没有函数名,所以我们没办法像有名函数那样调用它,我们需要把匿名函数保存到某个变量或者作为立即执行函数

作为变量调用

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. //将匿名函数保存到add变量
  7. add := func(x,y int) int {
  8. return x+y
  9. }
  10. add(3,3)
  11. }

直接执行匿名函数

  1. func main() {
  2. }
  3. package main
  4. import (
  5. "fmt"
  6. )
  7. func main() {
  8. //定义完匿名函数加()直接执行
  9. func (x int) {
  10. fmt.Println("直接调用匿名函数:",x)
  11. }(5)
  12. }

闭包

内层的匿名函数中包含了对外层函数的局部变量调用

  1. //adder函数, 返回值类型是func() int
  2. func adder() func() int{
  3. var x int=3
  4. return func() int {
  5. return x*x //访问外层函数的局部变量
  6. }
  7. }
  8. func main() {
  9. //在外部调用函数,访问变量x
  10. var result func() int =adder()
  11. fmt.Println(result())
  12. }