实践篇2|青训营

52 阅读1分钟

入门指南之一等函数

一、一等函数

  • 在Go语言里,函数是头等的,它可以用在整数、字符串或者其它类型能用的地方:
    • 将函数赋给变量
    • 将函数作为参数传递给函数

1、将函数赋给变量

  • 变量sensor就是一个函数,而不是函数执行的结果
  • 无论sersor的值是fakeSensor还是realSensor,都可以通过sensor()来调用
  • sensor这个变量的类型是函数,该函数没有参数,返回一个kelvin类型的值
  • 换一种声明形式的话:
    • var sensor func() kelvin

例子

type kelvin float64

func fakeSensor() kelvin {
      return kelvin(rand.Int(151) + 150)
}

func realSensor() kelvin {
      return 0
}

func main() {
     sensor := fakeSensor
     fmt.Println(sensor())
     
     sensor = realSensor
     fmt.Println(sensor())
}

2、将函数传递给其它函数

例子

 type kelvin float64

func measureTeperature(samples int, sensor func() kelvin) {
      for i := 0; i < samples; i++ {
          k := sensor()
          fmt.Printf("%v° K\n", K)
          time.Sleep(time.Second)
      }
}

func fakeSensor() kelvin {
     return kelvin(rand.Intn(151) + 150)
}

func main() {
   measureTemprature(3, fakeSensor)
}

3、声明函数类型

  • 为函数声明类型有助于精简和明确调用者的代码
    • 例如:type sensor func() kelvin
    • 所以:func measureTemerature(samles int,s func() kelvin)
    • 可以精简为:func measureTemperature(samples int, s sensor)

4、闭包和匿名函数

  • 匿名函数就是没有名字的函数,在Go里也称作函数字面值。

例子

var f = func() {
    fmt.Println("Dress up for the masquerade.")
}

func main() {
     f()
}
  • 因为函数字面值需要保留外部作用域的变量引用,所以函数字面值都是闭包的。

例子

type kelvin float64

type sensor func() kelvin

func realSensor() kelvin {
     reutrn 0
}

func calibrate(s senor,offset kelvin) sensor {
     reutrn func() kelvin {
         return s() + offset
     }
}

func main() {
    sencor := calibrate(realSencor, 5)
    fmt.Println(sensor())
}
  • 闭包(closure)就是由于匿名函数封闭并包围作用域中的变量而得名的。