浅浅复习一下 golang 函数

76 阅读2分钟

函数 func

一、函数声明

  • 函数名称
  • 形参列表
  • 返回列表
  • 函数体
  1. 形参列表

    指定了一组变量的参数名参数类型,属于局部变量,由调用者提供的**实参*(按值传递)***传递而来

  2. 返回列表

    指定了函数的返回值,可以为空

    当存在返回值时,必须显式声明return

    func 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中函数可以递归调用,即函数可以直接或间接地调用自身

三、错误处理

  • 通用策略

    将错误传递下去,使在子例程序中的错误传递到主调程序中的错误,并抛出错误

  • 重复策略

    对于不固定或者不可预测的错误,在短暂的隔离后进行重试,超出一定重试次数或限制时间后,抛出错误

  • 恐慌策略

    抛出错误并引发程序恐慌

四、函数变量

  1. 函数类型的零值为nil,会引发程序恐慌从而发生宕机

  2. 函数本身不可以比较,但是函数变量可以使数据进行参数化,也可以将函数的行为作为参数传递

    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))

七、延迟函数

  1. defer函数生效后,return 语句或panic语句才会生效
  2. defer函数可以无限次调用
  3. 当存在多个defer函数时,倒序调用defer函数