美文网首页
go 的函数式编程

go 的函数式编程

作者: OOM_Killer | 来源:发表于2019-08-01 23:37 被阅读0次

    在 go 语言中,函数是一等公民。函数既可以作为参数传入,也可以作为返回值返回。
    go 语言的函数式编程最典型的例子就是 闭包。

    闭包是什么呢?

    简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。
    它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。
    外部函数调用之后其变量对象本应该被销毁,但闭包的存在使我们仍然可以访问外部函数的变量对象,这就是闭包的重要概念。

    闭包
    package main
    
    import "fmt"
    
    func fib() func() int {
        a,b := 0,1
        return func() int {
            b,a = a+b,b
            return b
        }
    }
    
    func main() {
        f := fib()
        for i := 0 ; i < 20;i++ {
            fmt.Printf("%d ",f())
        }
    }
    // 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946
    
    为函数生成接口

    上面的例子中,f() 是每执行一遍的话 ,会生成一个新的斐波那契数。可以把他实现成为一个read的接口。那么就可以使用 scanner.Scan()。像读文件一样打印斐波那契数列。

    package main
    
    import (
        "bufio"
        "fmt"
        "io"
        "strings"
    )
    
    func fib() IntGen {
        a,b := 0,1
        return func() int {
            b,a = a+b,b
            return b
        }
    }
    
    type IntGen func() int
    
    func (g IntGen) Read(p []byte) (n int,err error) {
        next := g()
        if next > 1000000 {
            return 0,io.EOF
        }
        s := fmt.Sprintf("%d ",next)
        return strings.NewReader(s).Read(p)
    }
    
    func PrintFib(read io.Reader) {
        scanner := bufio.NewScanner(read)
    
        for scanner.Scan() {
            fmt.Println(scanner.Text())
        }
    }
    func main() {
        f := fib()
        PrintFib(f)
    } 
    
    传入函数来解决问题

    假设现在有一个遍历二叉数的函数。他只是做了打印的操作,那能否使用之前的所学到的知识,再丰富其功能呢。

    func (t *TreeNode) Traverse() {
        if t == nil {
            return
        }
    
        t.Left.Traverse()
        fmt.Println(t.Val)
        t.Right.Traverse()
    }
    

    用闭包改造后,不仅可以打印出每一个值,而且可以打印出一共有多少个节点。

    func (t *TreeNode) Traverse() {
        cnt := 0
        t.TraverseFunc(func(node *TreeNode) {
            fmt.Printf("%d ",node.Val)
            cnt ++
        })
        fmt.Println("\nNode cnt is",cnt)
    }
    
    func (t *TreeNode) TraverseFunc(f func (*TreeNode) ) {
        if t == nil {
            return
        }
    
        t.Left.TraverseFunc(f)
        f(t)
        t.Right.TraverseFunc(f)
    }
    

    相关文章

      网友评论

          本文标题:go 的函数式编程

          本文链接:https://www.haomeiwen.com/subject/dtuhdctx.html