7、一等函数-GOLANG

函数赋值给变量

气象传感器

气象传感器回提供150-300区间的开氏温度,我们创建一个待实现的真实传感器以及一个随机数的虚假传感器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import (
"fmt"
"math/rand"
)

type kelvin float64

func fakeSensor() kelvin{
return kelvin(rand.Intn(151)+150)
}
func realSensor() kelvin{
return 0
}
func main() {
var sensor func() kelvin//声明一个函数类型的变量sensor,返回值为kelevin类型
sensor = fakeSensor//注意这个地方直接吧函数fakeSensor本身赋值给sensor,没有加括号就是没有调用函数
fmt.Println(sensor())

}

函数传递给其他函数

需求:每两秒调用一次虚假传感器函数,那我们需要借助循环实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package main

import (
"fmt"
"math/rand"
"time"
)

type kelvin float64

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

func fakeSensor() kelvin {
return kelvin(rand.Intn(151) + 150)
}
func realSensor() kelvin {
return 0
}
func main() {
timeSensor(3, fakeSensor)

}

闭包与匿名函数

匿名函数:没有名字的函数

1
2
3
4
5
6
7
8
9
10
package main

import "fmt"

func main() {
f := func(s string) {
fmt.Println(s)
}
f("xiu")//也可以不赋值给f,直接在匿名函数大括后面加一个小括号
}

闭包:一个外层函数定义了一个局部变量,它的内层函数修改了这个局部变量,外层函数的返回值就是该内层函数,这就是闭包,听起来有点懵,上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import "fmt"

func increment() func() int {
i := 0
fun := func() int {
i++
return i
}
return fun
}

func main() {
r1 := increment()
fmt.Println(r1())
fmt.Println(r1())
fmt.Println(r1())

r2 := increment()//重新把increment赋值给一个新变量,正常来说局部变量i的值已经重置
fmt.Println(r2())
fmt.Println(r2())
fmt.Println(r2())
fmt.Println(r2())
fmt.Println(r2())

fmt.Println(r1())//再次打印r1,结果发现局部变量生命周期发生改变,并没有随着r2变更
}

代码执行结果

image-20230308131848310