GO函数式编程详解及练习

GO是函数式编程,不是面像对象的语言,它没有对象的概念,一切都是根据结构体去分配内存,GO中的函数也是如此。

先上一段代码:

package main

import "fmt"

func adder1() func(i int) int  {
	sum := 0
	return func(v int) int {
		sum += v
		return sum
	}
}
func main() {
	//a := adder1()表达式应该是得到下面这个函数
	//return func(v int) int {
	//	sum += v
	//	return sum
	//}
	a := adder1()

	//每次往a函数中传入参数都会得到自加
	//sum := 0 -> sum是个函数闭包内的自由变量
	for i := 0;i<10 ;i++  {
		fmt.Println(a(i))
	}
}

代码中已经加了比较详细的注释,当a=adder1()时编译器会返回一个函数的闭包。
函数体部分是:

return func(v int) int {
			sum += v
			return sum
		}

sum是函数体的自由变量,这个变量也可以是结构体,如果是结构体的话还可能会引用到外部的变量,会形成一棵引用树,最终都会被包括到函数的闭包中。
在这里插入图片描述

篇外话,正统的函数式编程是不可以有状态和变量了,当然就GO来说对此无要求。
按照函数式编程的定义,本段代码应该改成这个样子:

package main

import "fmt"

type iAdder func(i 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.Printf("0+1+...%d = %d\n",i,s)
	}
}

这个函数中只有常量和函数体,是正统的函数式编程,当这个没有上面的代码好理解

再来一段复杂点的,让fibonacci数列实现Reader接口,以函数的方式来读取

package main

import (
	"bufio"
	"fmt"
	"io"
	"strings"
)

type intGen func() int

func (g intGen)Read(p []byte)(n int,err error)  {
	next := g()
	if next > 1000 {
		return 0,io.EOF
	}
	s := fmt.Sprintf("%d\n",next)
	return strings.NewReader(s).Read(p)
}

func iAdder() intGen {
	a,b := 0,1
	return func() int {
		 a,b = b,a+b
		 return a
	}
}

func printFileContens(reader io.Reader)  {
	scanner := bufio.NewScanner(reader)

	for scanner.Scan(){
		fmt.Println(scanner.Text())
	}
}

func main() {
	f := iAdder()
	printFileContens(f)
}

没什么好说的,代码可直接运行,对着敲几遍就明白了

猜你喜欢

转载自blog.csdn.net/wangqiang9x/article/details/88528917