函数式编程 vs 函数指针
- 函数是一等公民:参数、变量,返回值都可以是函数
- 高阶函数:参数可以是一个函数
- 函数->闭包
“正统”函数编程
- 不可变性:不能有状态,只有常量和函数
- 函数只能有一个参数
闭包
package main
import "fmt"
func adder() func (int) int {
sum := 0
return func (v int) int {
sum += v
return sum
}
}
func main() {
a := adder()
for i := 0; i < 10; i++ {
fmt.Printf("0 + 1 + ... + %d = %d\n",
i, a(i))
}
}
修改为正统函数式编程
package main
import "fmt"
func adder() func(int) int {
sum := 0
return func(v int) int {
sum += v
return 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() {
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)
}
}
python 中的闭包
def adder():
sum = 0
def f(value):
nonlocal sum
sum += value
return sum
return f
- python 原生支持闭包
- 使用__closure__来查看闭包内容
go 语言闭包应用
斐波那契数列
package main
import (
"fmt"
)
func fibonacci() intGen {
a,b := 0,1
return func() int {
a, b = b, a + b
return a
}
}
func main() {
f := fibonacci()
fmt.Println(f()) //1
fmt.Println(f())//1
fmt.Println(f())//2
fmt.Println(f())//3
fmt.Println(f())//5
fmt.Println(f())//8
fmt.Println(f())//13
fmt.Println(f())//21
fmt.Println(f())//34
}
为函数实现接口
package main
import (
"fmt"
"io"
"bufio"
"strings"
)
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 > 10000 {
return 0, io.EOF
}
s := fmt.Sprintf("%d\n", next)
return strings.NewReader(s).Read(p)
}
func printFileContents(reader io.Reader) {
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}
func main() {
f := fibonacci()
printFileContents(f)
}
使用函数来遍历二叉树
#node.go
package tree_7
import "fmt"
type TreeNode struct {
Value int
Left,Right *TreeNode
}
func CreatNode(value int) *TreeNode {
return &TreeNode{Value:value}
}
/*结构体得方法*/
func (node TreeNode) Print() {
fmt.Println(node.Value)
}
func (node *TreeNode) SetValue(value int) {
node.Value = value
}
func (node *TreeNode) Traverse() {
node.TraverseFunc(func (n *TreeNode) {
n.Print()
})
fmt.Println()
}
func (node *TreeNode) TraverseFunc(f func(*TreeNode)) {
if node == nil {
return
}
node.Left.TraverseFunc(f)
f(node)
node.Right.TraverseFunc(f)
}
#main.go
package main
import (
"fmt"
"awesomeProject/7-3"
)
func main() {
var root tree_7.TreeNode
root = tree_7.TreeNode{Value:3}
root.Left = &tree_7.TreeNode{}
root.Right = &tree_7.TreeNode{5,nil,nil}
root.Left.Right = tree_7.CreatNode(2)
root.Right.Left = new(tree_7.TreeNode)
root.Right.Left.SetValue(4)
root.Traverse()
nodeCount := 0
root.TraverseFunc(func(n *tree_7.TreeNode) {
nodeCount++
})
fmt.Println("Node count:", nodeCount)
}