6、go语言:函数式编程

1、函数式编程

函数和闭包,go语言对函数式编程主要体现在闭包的能力

//累加器函数
func adder () func (value int) int {
	sum := 0
	return func(value int) int {
		sum += value
		return sum
	} //返回的是闭包
}

func main(){
	adder := adder()
	for i:= 0 ; i< 10;i++{
		fmt.Println(adder(i))
	}
}

//0+1+...+i

函数式编程VS函数指针:
函数是一等公民:参数,变量,返回值都可以是函数(C++函数只是指针)
高阶函数
函数->闭包

”正统“函数式编程:(数学味道太浓)
不可变性:不能有状态,只有常量和函数
函数只能有一个参数

闭包:
函数体:
局部变量
自由变量(sum)连接其他变量

//不能有状态,正统函数
type iAdder func(int) (int,iAdder)

func adder2(base int) iAdder{
	return func(v int) (int,iAdder){
		return base +v,adder2(base + v )
	}
}
func main(){
	adder := adder2(0)
	for i:= 0 ; i< 10;i++{
		var s int
		s,a = adder(i)
		fmt.Println(adder(i),s)
	}
}

//pthon中的闭包
def adder():
	sum=0
	def f(value):
		nonlocal sum //需要生命
		sum += value
		return sum
	return f
//python原生支持闭包
//使用__closure__来查看闭包内容

//c++中的闭包 C++14才编译通过
auto adder(){
	auto sum =0 ;
	return [=] (int value) mutable {
		sum += value;
		return sum;
	};
}
//过去:stl或者boost带有类似库 //模拟闭包
//C++11及以后:支持闭包

//java中的闭包:
function<Integer,Integer> adder(){
	final Holder  <Integer> sum = new Holder<>(0);
	return (Integer value) -> {
		sum.value += value;
		return  sum.value;
	};
}

sum不能改变,sum.value可以改变
1.8以后:使用Function接口和Lamba表达式来创建函数对象
匿名类或Lamba表达式均支持闭包

go闭包的应用:斐波那契数列

//a,b
//   a,b
func fibonacci() func() int {
	a,b := 0,1
	return func() int {
		a,b = b,a+b
		return a
	}
}


func main(){
	f := fibonacci()
	f() //1
	f() //1
	f() //2
	f() //3
	f() //5
	f() //8
	f() //13
	f() //21

}

//go闭包的应用 :为函数实现接口

//使用生成器
func fibonacci() intGen {
	a,b := 0,1
	return func() int {
		a,b = b,a+b
		return a
	}
}

type intGen func() int //函数类型,是一个类型,就可以实现一个接口

func (g intGen) Read(p []byte) (n int,err error){ //函数也可以实现接口,函数是一等公民,也可以作为接收者
	next := g()
		if next > 1000{
		return 0,io.EOF //大于10000文件读到头
	}
	s := fmt.Sprintf("%d\n",next) //用string来代理Read,因为其已经实现了这个接口
	// TODO : incorrect if p is too small!
	return strings.NewReader(s).Read(p) //这样函数就实现了Read接口
}

//go闭包的应用 :使用函数来遍历二叉树
func (node *Node) Traverse(){
	node.TraverseFunc(func(node *Node){
		node.Print()
	})
	fmt.Println()
}

func (node *Node) TraverseFunc (f func(*Node)){
	if node == nil {
		return
	}
	node.Left.TraverseFunc(f)
	f(node)
	node.Right.TraverseFunc(f)
}

//数一数函数有多少值
nodeCount := 0
root.TraverseFunc(func(node *tree.Node){
	nodeCount++
})
fmt.Println("Node count:",nodeCount)

go语言闭包:
更为自然,不需要修饰如何访问自由变量
没有Lamba表达式,但是有匿名函数

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值