Learn Go (七) 函数式编程

定义

函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论

特性

  • 函数是一等公民: 参数, 变量, 返回值都可以是函数;

  • 只用"表达式", 不用"语句";

  • 高阶函数和闭包;

    image.png
    func adder() func(int) int {
       sum := 0
       return func(v int) int {
          sum += v
          return sum
       }
    }
    
  • 不修改状态;

  • 递归

应用

斐波那契数列

func fibonacci() func() int {
   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

}

为函数声明接口

// 定义类型
type intGen func() int

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

}

func printFileContents(reader io.Reader) {
    scanner := bufio.NewScanner(reader)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

func main() {
    f := fibonacci()
    printFileContents(f)
}
// 结果

1
1
2
3
.
.
.
4181
6765

使用函数遍历二叉树

修改下遍历节点的代码.

  • tree/node 原内容

     package tree
    
     import "fmt"
    
     type Node struct {
        Value int
        Left, Right *Node
     }
    
     func CreateNode(value int) *Node  {
        return &Node{Value: value}
     }
    
     func (node Node) Print()  {
        fmt.Println(node.Value)
     }
    
     func (node *Node) SetValue(value int)  {
        node.Value = value
     }
     
     func (node *Node) Traverse()   {
        node.TraverseFunc(func(no *Node) {
           no.Print()
        })
        fmt.Println()
     }
    
  • 同级目录新建文件 travelsal.go

    package tree
    
    import "fmt"
    
    // 接口, 这个函数是从上面拿下来的
    func (node *Node) Traverse()   {
       node.TraverseFunc(func(no *Node) {
          no.Print()
       })
       fmt.Println()
    }
    
    // 将函数作为参数
    func (node *Node) TraverseFunc(f func(*Node))  {
       if node == nil {
          return
       }
    
       node.Left.TraverseFunc(f)
       f(node)
       node.Right.TraverseFunc(f)
    }
    

优点

  • 代码简洁, 开发快速
  • 更为自然, 不需要修饰如何访问自由变量
  • 接近自然语言, 易于理解
  • 更方便的代码管理
  • 易于"并发编程"
  • 代码的热升级

你可能感兴趣的:(Learn Go (七) 函数式编程)