函数式编程

函数的数据类型

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万+ 他的留言板 关注
上一篇:python——类中的self和变量


下一篇:面试题64:求1+2+……+n