GO语言函数编程-闭包
概念
go语言对于函数编程的主要支持,主要体现在闭包函数上。
- 函数是一等公民:参数、变量、返回值都可以是函数
- 高阶函数
- 函数闭包
正统函数式编程要求: - 不可变性:不能有状态,只有常量和函数
- 函数只有一个参数
go是一门通用语言,不会要求这么严格。
GO函数闭包
函数体有局部变量,自由变量。自由变量就会连接一根线,自由变量可以是个结构,结构连接结构最后连接成一棵树。寻找连接关系不断的连接下去,最后把我们所有需要连接的东西连接完成。全部连到之后,就叫做一个闭包。所以当函数返回的时候返回的是一个闭包函数。
示例代码:
package main
import "fmt"
//定义一个闭包函数 实现累加功能
func adder() func (num int) int {
sum := 0 //sum就是自由变量
return func(num int) int{
sum += num //num 是局部变量
return sum
} //返回的是一个闭包函数
}
func main(){
a := adder();
for i:=0;i<10;i++ {
anum := a(i)
fmt.Printf("0+...+%d = %d\n",i,anum)
}
}
没有自由变量的函数式编程(正统的函数编程写法)
package main
import "fmt"
type iAdder func(v int) (int,iAdder)
func Adder(base int) iAdder { //没有自由变量的函数编程
return func(v int) (int,iAdder){
return base+v,Adder(base+v)
}
}
func main(){
a := Adder(0)
var sum int
for i := 1 ; i<10 ;i++ {
sum , a = a(i)
fmt.Printf("0+...+%d = %d\n",i,sum)
}
}
函数编程实现斐波那契数列
1,1,2,3,5 最前面两个数固定是1,后面数的规律是当前数前面两个数的和
package main
import "fmt"
//使用闭包函数实现斐波那契数列
func fibonacci() func() int{
a,b := 0,1
return func()int{ //后一个数替换前一个数
a,b = b,a+b
return a
}
}
//斐波那契数列 当前数是前面两个数的合
func main(){
f := fibonacci()
for i := 1 ; i < 11 ; i++ {
fmt.Println(f())
}
}
其中 f 就像fibonacci数的生成器一样,我们可以把 f 封装成一个文件reader一直读它,如果f实现了reader接口,就可以使用bufio读取文件。下面是优化的代码:
package main
import (
"bufio"
"fmt"
"io"
"strings"
)
//自定义函数类型
type Fnc func() int
//实现reader接口 函数类型也可以是方法的接受者
func (f Fnc)Read(p []byte)(n int,err error){
num := f()
if num < 10000 {
s := fmt.Sprintf("%d\n",num)
//TODO: 若是num很大怎么处理?p装不下了只能读取一部分
return strings.NewReader(s).Read(p)
}
return 0,io.EOF
}
//使用闭包函数实现斐波那契数列
func fibonacci() Fnc{
a,b := 0,1
return func()int{ //后一个数替换前一个数
a,b = b,a+b
return a
}
}
//斐波那契数列 当前数是前面两个数的合
func main(){
f := fibonacci()
PrintContent(f)
}
func PrintContent(reader io.Reader){
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}