009. golang 函数 function

╰半橙微兮° 2021-10-06 15:06 424阅读 0赞

函数function

  • Go 函数 不支持 嵌套、重载和默认参数
  • 但支持以下特性:

    1. 无需声明原型、不定长度变参、多返回值、命名返回值参数
    2. 匿名函数、闭包
  • 定义函数使用关键字 func,且左大括号不能另起一行
  • 函数也可以作为一种类型使用

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. fmt.Println(A(1, "a"))
  7. fmt.Println(B(2, "b"))
  8. a, b, c := 1, 2, 3
  9. C("y", a, b, c)
  10. fmt.Println(a, b, c)
  11. arr := []int{1, 2, 3, 4, 5, 6}
  12. D(arr)
  13. fmt.Println(arr)
  14. e := 2
  15. E(&e)
  16. fmt.Println(e)
  17. }
  18. func A(a int, b string) (int, string) {
  19. return a, b
  20. }
  21. func B(a int, b string) (A int, B string) {
  22. A, B = a, b
  23. return
  24. }
  25. //不定长变参,只能作为最后一个参数 而且拷贝的都是值拷贝
  26. func C(x string, a ...int) {
  27. a[0] = 4
  28. a[1] = 5
  29. a[2] = 6
  30. fmt.Println(x, a)
  31. }
  32. //数组的话都是地址拷贝
  33. func D(a []int) {
  34. a[0] = 10
  35. a[1] = 11
  36. a[2] = 12
  37. fmt.Println(a)
  38. }
  39. //如果 值拷贝 想更改为 地址拷贝
  40. //传参数的时候加上 &
  41. //方法形参加上 *
  42. func E(e *int) {
  43. *e = 9
  44. fmt.Println(*e)
  45. }

这里写图片描述


  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. //匿名函数
  7. a := func() {
  8. fmt.Println("Func A")
  9. }
  10. a()
  11. fmt.Println()
  12. //匿名函数+闭包
  13. f := test(10)
  14. fmt.Println("------------------------")
  15. fmt.Println(f(1))
  16. fmt.Println(f(2))
  17. }
  18. func test(x int) func(int) int {
  19. fmt.Printf("%p,%d\n", &x, x)
  20. return func(y int) int {
  21. fmt.Printf("%p,%d\n", &x, x)
  22. return x + y
  23. }
  24. }

这里写图片描述


defer

  • 执行方式类似其它语言中的析构函数,在函数体执行结束后
  • 按照调用顺序的相反顺序逐个执行
  • 即使函数发生严重错误也会执行
  • 支持匿名函数的调用
  • 常用于资源清理文件关闭解锁以及记录时间等操作
  • 通过与匿名函数配合可在return之后修改函数计算结果
  • 如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer
  • 时即已经获得了拷贝,否则则是引用某个变量的地址
  • Go 没有异常机制,但有 panic/recover 模式来处理错误
  • Panic 可以在任何地方引发,但recover只有在defer调用的函数中有效,而且得在panic前面

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. fmt.Println("a")
  7. defer fmt.Println("b")
  8. defer fmt.Println("c")
  9. fmt.Println("------------------")
  10. for i := 0; i < 3; i++ {
  11. defer func() {
  12. fmt.Println(i)
  13. }()
  14. }
  15. fmt.Println("---------------")
  16. }

这里写图片描述


  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. A()
  7. B()
  8. C()
  9. }
  10. func A() {
  11. fmt.Println("func A")
  12. }
  13. func B() {
  14. panic("panic in B")
  15. }
  16. func C() {
  17. fmt.Println("func C")
  18. }

这里写图片描述


  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. A()
  7. B()
  8. C()
  9. }
  10. func A() {
  11. fmt.Println("func A")
  12. }
  13. func B() {
  14. defer func() {
  15. if err := recover(); err != nil {
  16. fmt.Println("recover in B")
  17. }
  18. }()
  19. panic("panic in B")
  20. }
  21. func C() {
  22. fmt.Println("func C")
  23. }

这里写图片描述


  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var fs = [4]func(){} //声明一个function类型的slice,长度为4
  7. for i := 0; i < 4; i++ {
  8. defer fmt.Println("defer i= ", i) //这是一个i作为参数传进去的输出,因为i是int型,所以遵循一个规则值拷贝的传递,还有defer是倒序执行的,所以先后输出3,2,1,0,跟下面的defer交替执行4次
  9. defer func() { fmt.Println("defer_closure i = ", i) }() //执行完下面的代码后,到了该defer了,这也是一个匿名函数,同样的也没有参数,也没有定义i,所以这也是个闭包,用的也是外面的i,所以先输出4,接着执行上面的defer,这样反复执行4次
  10. fs[i] = func() { fmt.Println("closure i = ", i) } //把相应的4个匿名函数存到function类型的slice里,因为这是个匿名函数,又没有参数,且也没有定义i,所以i就是外层函数的地址引用,就是for循环的i的地址,执行完for后i的值为4,所以输出4个4
  11. }
  12. for _, f := range fs { //用for循环对slice的调用,f为slice的值,即匿名函数,而f()则是对匿名函数的调用
  13. f()
  14. }
  15. }

这里写图片描述

发表评论

表情:
评论列表 (有 0 条评论,424人围观)

还没有评论,来说两句吧...

相关阅读

    相关 golang函数

    函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段,其可以提高应用的模块性和代码的重复利用率。 Go 语言支持普通函数、匿名函数和闭包,从设计上对函数进行了优化和