函数的数据类型
Go语言中的函数可以作为一种复合的数据类型。
package main
import "fmt"
func fun1(a, b int) {
fmt.Println("a:", a, ",b:", b)
}
func fun2(a, b int) int {
return a + b
}
func main() {
// 函数作为一个变量
fmt.Printf("%T:\t", fun1)
fmt.Println(fun1) //func(int, int): 0x498450
// 直接定义一个函数类型的变量
var c func(int, int)
fmt.Printf("%T:\t", c)
fmt.Println(c) // func(int, int): <nil>
c = fun1; //将fun1的值(函数体的地址),赋值给c
fmt.Println(c) //0x498450
fun1(10, 20) // 调用函数 a: 10 ,b: 20
c(100, 200) // 调用函数 a: 100 ,b: 200
res1 := fun2 //将fun2的值(函数的地址),赋值给res1,res1和fun2指向同一个函数体
res2 := fun2(1, 2)//将fun2函数进行调用,将函数的执行结果,赋值给res2,相当于:res = a+b
fmt.Println(res2) // 3
fmt.Println(res1) //0x498590
fmt.Println(res1(10,20)) //30
}
函数的本质
package main
import "fmt"
func main() {
/*
函数作为一种复合的数据类型,可以将函数也看做是一种变量。
*/
//1.作为一个int类型的变量的常规操作
var num1 int
num1 = 100
fmt.Println(num1) //100
//2.将一个函数看成一个变量的操作
fmt.Printf("%T\n",fun1) // func(int,int)int
var a func(int,int)int
a = fun1 // 将fun1赋值给a
fmt.Printf("%T\n",a)
r1:=a(1,2) //a作为一个函数的变量,可以直接被调用
fmt.Println(r1) // 3
r2:=fun1(10,20)
fmt.Println(r2)
b := fun1 //将fun1直接赋值给b,那么b是func函数,
c := fun1(100,200)//将fun1的执行结果赋值给c,int类型的数据
b(1,2)
//c()
fmt.Println(c)
fmt.Printf("%v\n",fun1)
fmt.Printf("%v\n",a)
fmt.Printf("%v\n",b)
}
func fun1(a, b int) int{ // func(int,int)int
return a + b
}
匿名函数
匿名函数,就是没有名字的函数。
定义一个匿名函数,直接进行调用。通常只能使用一次。也可以将匿名函数赋值给某个函数变量。那么可以调用多次。
匿名函数:
1.将函数作为另一个函数的参数。回调函数
2.将函数作为另一个函数的返回值。
package main
import "fmt"
func fun1(){
fmt.Println("我是fun1函数。。")
}
func main() {
fun1()//调用函数
fun2:=fun1
fun2()//调用函数
//匿名函数:
func (){
fmt.Println("我是一个匿名函数。。")
}()
fun3:=func(){
fmt.Println("我也是一个匿名函数。。")
}
fun3()
fun3()
//定义带参数的匿名函数
func(a, b int){
fmt.Println(a, b)
}(1,2)
//定义带返回值的函数
res1:=func(a, b int)int{
return a + b
}(10,20) //匿名函数调用了,将调用执行的结果给res1
fmt.Println(res1)
res2 :=func(a,b int)int{
return a+b
}//将匿名函数的值,赋值给res2
fmt.Println(res2) // 0x496910
}
回调函数
高阶函数:
根据go语言的数据类型的特点,可以将一个函数作为另一个函数的参数。
fun1(),fun2()
将fun1函数作为了fun2这个函数的参数。
fun2函数:就叫高阶函数
接收了一个函数作为参数的函数,高阶函数
fun1函数:回调函数
作为另一个函数的参数的函数,叫做回调函数。
package main
import "fmt"
//加法运算
func add(a, b int) int{
return a + b
}
func sub(a, b int)int{
return a-b
}
func oper(a, b int,fun func (int,int)int) int{
fmt.Println(a,b,fun)//打印3个参数
res := fun(a, b)
return res
}
func main() {
fmt.Printf("%T\n",add) //func(int, int) int
fmt.Printf("%T\n",oper) //func(int, int, func(int, int) int) int
res1 := add(1,2)
fmt.Println(res1)
res2 := oper(10,20,add)
fmt.Println(res2)
res3:=oper(5,2,sub)
fmt.Println(res3)
fun1:=func (a, b int)int{
return a * b
}
res4:=oper(10,4,fun1)
fmt.Println(res4)
res5:=oper(100,8, func(a int, b int) int {
if b == 0 {
fmt.Println("除数不能为令")
return 0
}
return a / b
})
fmt.Println(res5)
}
闭包
go语言支持函数式编程
支持将一个函数作为另一个函数的参数
也支持将一个函数作为另一个函数的返回值。
闭包(closure):
一个外层函数中,有内层函数,该内层函数中,会操作外层函数中的局部变量(外层函数中的参数,或者外层函数直接定义的变量),并且该外层函数的返回值就是这个内存函数。
局部变量的生命周期会发生改变,正常的局部变量随着函数的调用而创建,随着函数的结束而销毁。
但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而销毁,因为内层函数还要继续使用。
package main
import "fmt"
//可以将一个函数作为返回值。
func increment() func()int{//外层函数
//1.定义了一个局部变量
i := 0
//2.定义了一个匿名函数,给变量自赠了并返回
fun := func ()int{//内层函数
i++
return i
}
//3.返回该匿名函数
return fun
}
func main() {
res1:=increment() //res1 = fun
fmt.Printf("%T\n",res1) //func() int
fmt.Println(res1) //0x498570
v1:=res1()
fmt.Println(v1)//1
v2 :=res1()
fmt.Println(v2)//2
fmt.Println(res1())//3
fmt.Println(res1())//4
fmt.Println(res1())//5
fmt.Println(res1())//6
res2:=increment()
v3:=res2()
fmt.Println(v3) //1
v4:=res2()//2
fmt.Println(v4)
v5 := res1()
fmt.Println(v5)//7
}
Ocean&&Star
发布了255 篇原创文章 · 获赞 71 · 访问量 20万+
关注