赞
踩
"正统"函数式编程特点如下
.不可变性:不能有状态,只有常量和函数
.函数只能有一个参数
但go语言区别于“正统”函数式编程 go语言是面向大众的语言 所以不会在语法上纠结正统不正统
下面先看一个函数式编程 闭包 的例子
- package main
-
- import "fmt"
-
- func Adder() func(v int) int{ //闭包 返回值为匿名函数
- sum := 0 //自由变量 自由变量我的理解是此函数内有效的不被回收的值
- return func(v int)int{ //返回值为函数 完成闭包流程
- sum += v //sum为叠加 不会被释放
- return sum
- }
- }
- func main(){
- a := Adder() //将函数作为变量赋值给a是函数式编程的特点
- for i:= 0; i < 10; i++{
- fmt.Println(a(i)) //打印闭包返回值 i值实际是向Adder()的匿名函数赋值
- }
- }
比较一下正统的函数式编程
- 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(){
- a := adder2(0)
- for i:= 0; i < 10; i++{
- var s int
- s, a = a(i)
- fmt.Println(s)
- }
- }
区别是不是很大
下面再举一个例子
- package main
-
- import "fmt"
-
- func fibonacco()func () int{
- a, b:= 0,1
- return func()int{
- a,b = b, a+b
- return a
- }
- }
-
- func main(){
- a := fibonacco()
- for i:=0; i< 10; i++ {
- fmt.Println(a())
- }
- }
这是典型的斐波那契算法 用go语言实现显得很简洁
下面是用函数作为类型 定义接口 进行函数运算
- package main
-
- import (
- "fmt"
- "io"
- "bufio"
- "strings"
- )
-
- func fibonacco()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){ //定义接口 go语言中任何类型都可以实现接口 函数只是一个特殊的参数
- next := g() //next是 类型传输值
- if next > 10000{ //限制无限循环
- return 0,io.EOF
- }
- s := fmt.Sprintf("%d\n",next) //将整形转化为字符串 strings.NewReader使用
- return strings.NewReader(s).Read(p) //使用s做打印 p为uint8可使用位数
- }
- func printFileContents(reader io.Reader){ //打印任何类型
- scanner := bufio.NewScanner(reader) //将函数转换 赋值给scanner
-
- for scanner.Scan() { //将scanner里面的值全部循环打印出来
- fmt.Println(scanner.Text())
- }
- }
- func main(){
- a := fibonacco()
- printFileContents(a)
- }
由上可得出 go语言中 函数式编程可用函数作为类型 将函数类型传递到函数里面直接可以使用
下面再来一个例子
- package tree
-
- import "fmt"
-
- type Node struct{ //二叉树
- Value int
- Left,Right *Node
- }
- func CreateNode(r int) *Node{
- return &Node{r,nil,nil}
- }
- func (node *Node)SetValue(v int){
- node.Value = v
- }
- func (node *Node)printf(){
- fmt.Println(node.Value)
- }
- func (node *Node)Traverse(){ //需要注意的地方在这
- node.TraverseFunc(func (n *Node){ //函数做参数传递 明确的表现出函数式编程
- n.printf() //n值由递归不断赋值 每次打印内容不相同
- })
- }
-
- func (node *Node)TraverseFunc(f func(*Node)){ //需要注意的地方在这 函数做参数传递 并且有形参f
- if node == nil{
- return
- }
- node.Left.TraverseFunc(f) //递归 同时传递f 我的理解是f值在递归返回之前 值不发生变化
- f(node) //f开始运作 f作为函数形参 并且函数为指针 node参数放入f中_
- //上方n形参指向地址改变 做出打印内容
- node.Right.TraverseFunc(f) //中序遍历 结束后打印剩余数据
- }
- package main
-
- import "awesomeProject1/test/shu/tree"
-
- func main(){
- root := tree.Node{3,nil,nil} //普通的二叉树赋值
- root.Left = &tree.Node{}
- root.Right = &tree.Node{Value:5}
- root.Right.Left = new(tree.Node)
- root.Left.Right = tree.CreateNode(2)
- root.Right.Left.SetValue(4)
-
- root.Traverse()
- }
总结go语言的函数式编程
.更为自然 不需要修饰如何访问自由变量
.没有lambda 但是具有匿名函数
.go语言闭包("函数式编程")个人认为是go语言的难点也是重点
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。