package main
import ("fmt")
type add func(a int, b int)int
func main(){
var a add = func(a int, b int)int{
return a + b
}
sum := a(2022,10)
fmt.Println("a + b = ", sum)}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
上面的程序中,我们定义了一个 add 类型的变量,并给它分配了一个签名与 add 类型相符的函数,接着通过 sum := a(2022,10) 调用并将结果赋给 sum,运行程序后得到如下的结果:
a + b =2032
1.
4.高阶函数
对高阶函数的定义是这个函数至少做到以下的某一项的功能:
以一个或者多个函数作为参数
返回一个函数作为其结果
将函数作为参数传递给其他函数
package main
import ("fmt")
func simple(a func(a, b int)int){
fmt.Println(a(60,7))}
func main(){
f := func(a, b int)int{
return a + b
}
simple(f)}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
我们定义一个函数 simple 函数,它接收两个 int 参数,并返回一个 int 参数,然后把匿名函数传给变量 f,然后把 f 作为参数传递给 simple 函数,最终这个程序将打印 67 输出:
67
1.
从其他函数中返回函数
现在让我们重写上面的程序,从 simple 函数中返回一个函数:
package main
import ("fmt")
func simple() func(a, b int)int{
f := func(a, b int)int{
return a + b
}
return f
}
func main(){
s := simple()
fmt.Println(s(2022,60))}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
运行该程序,得到结果;
2082
1.
5.闭包
闭包是匿名函数的一种特殊情况。闭包是匿名函数,它访问定义在函数主体之外的变量。
代码如下:
package main
import ("fmt")
func main(){
a :=2022
func(){
fmt.Println("a = ", a)}()}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
每个闭包都与它自己周围的变量绑定。让我们通过一个简单的例子来理解这意味着什么。
package main
import ("fmt")
func appendStr() func(string) string {
t :="Hello"
c := func(b string) string {
t = t +" "+ b
return t
}
return c
}
func main(){
a := appendStr()
b := appendStr()
fmt.Println(a("World"))
fmt.Println(b("Everyone"))
fmt.Println(a("Gopher"))
fmt.Println(b("!"))}
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
在上面的程序中,appendStr 函数返回一个闭包。这个闭包被绑定到变量 t 上,变量 a 和 b 是闭包,被绑定到它们自己的值 t 上。
我们传递参数 World 给 a,然后 a 的值变成了 Hello World。
传递参数 Everyone 给 b,然后 b 的值变成了 Hello Everyone 。
Hello World
Hello Everyone
Hello World Gopher
Hello Everyone !
package main
import ("fmt""sort")
func main(){
input :=[]string{"foo","bar","baz"}
var result []string
// closure callback
func(){
result = append(input,"abc")
result = append(result,"def")
sort.Sort(sort.StringSlice(result))}()
fmt.Println(result)}
func filter(s []student, f func(student)bool)[]student {
var r []student
for _, v := range s {
if f(v)==true{
r = append(r, v)}}
return r
}
1.
2.
3.
4.
5.
6.
7.
8.
9.
在上述函数中,filter 的第二个参数是一个函数,它以一个 student 为参数,返回一个 bool 。这个函数确定一个特定的学生是否符合某个标准。我们在第 3 行遍历学生切片。如果该函数返回真,则意味着该学生通过了过滤标准,并被添加到切片 r 中。
现在来看一个完整的程序:
package main
import ("fmt")
type student struct {
firstName string
lastName string
grade string
country string
}
func filter(s []student, f func(student)bool)[]student {
var r []student
for _, v := range s {
if f(v)==true{
r = append(r, v)}}
return r
}
func main(){
s1 := student{
firstName:"Naveen",
lastName:"Ramanathan",
grade:"A",
country:"India",}
s2 := student{
firstName:"Samuel",
lastName:"Johnson",
grade:"B",
country:"USA",}
s :=[]student{s1, s2}
f := filter(s, func(s student)bool{
if s.grade=="B"{
return true}
return false})
fmt.Println(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.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
在主函数中,我们首先创建了两个学生 s1 和 s2,并将他们添加到片断 s 中。现在我们假设要找出所有成绩为 B 的学生,在上述程序中,我们通过传递一个检查学生是否为 B 级的函数,如果是,则返回 true。 上述程序将打印:
[{Samuel Johnson B USA}]
1.
比方说,我们想找到所有来自印度的学生。这可以通过改变过滤器函数的参数来轻松实现。如下:
c := filter(s, func(s student)bool{
if s.country=="India"{
return true}
return false})
fmt.Println(c)
1.
2.
3.
4.
5.
6.
7.
让我们再写一个程序来结束本文。这个程序将对一个切片的每个元素进行同样的操作,并返回结果。
例如,如果我们想将一个切片中的所有整数乘以 5,并返回输出结果,可以用第一类函数轻松完成。
这类对集合中每个元素进行操作的函数被称为 map 函数。如下这个程序
package main
import ("fmt")
func iMap(s []int, f func(int)int)[]int{
var r []int
for _, v := range s {
r = append(r, f(v))}
return r
}
func main(){
a :=[]int{5,6,7,8,9}
r := iMap(a, func(n int)int{
return n *5})
fmt.Println(r)}