zoukankan      html  css  js  c++  java
  • Go的几种函数式编程范例

    函数一等公民,在Go中兼顾了函数式编程所以可以将func作为参数和返回值随意操作

    import "fmt"
    
    func main() {
        var list = []string{"Orange", "Apple", "Banana", "Grape"}
        var out = mapForEach(list, func(it string) int {
            return len(it)
        })
        fmt.Println(out)
    }
    
    func mapForEach(arr []string, fn func(it string) int) []int {
        var newArray = []int{}
        for _, it := range arr {
            newArray = append(newArray, fn(it))
        }
        return newArray
    }

    柯里化

    package main
    
    func main() {
        var add1 = add(1)
        println(add1(2))
    }
    
    func add(x int) func(y int) int {
        return func(y int) int {
            return x + y
        }
    }

    值得注意的一点是函数式编程本质就是:stateless和immutable,即使我们可以操作改变外部数据我们也不要做这样的尝试,因为它已经违背了原则。

    stateless:函数不维护任何状态。函数式编程的核心精神是 stateless,简而言之就是它不能存在状态,打个比方,你给我数据我处理完扔出来。里面的数据是不变的。

    immutable:输入数据是不能动的,动了输入数据就有危险,所以要返回新的数据集。

    错误的尝试

    var holder = map[string]int{}
    
    func sum(a, b int) int {
        c := a + b
        holder[fmt.Sprintf("%d+%d", a, b)] = c
        return c
    }

    一般递归

    func factorial(num int) int {
        if num == 0 {
            return 1
        } else {
            return num * factorial(num - 1)
        }
    }

    这种递归为什么不太好,因为我们的num在前半部递归树实际上是一直不变的,也就是说我们一直引用着前面的空间,这样容易出现溢出。

    尾递归

    func factorial(accumulator, num int) int {
        if num == 0 {
            return accumulator
        } else {
            return factorial(accumulator * num, num - 1)
        }
    }
    
    func factorialTailRec(num int) int {
        return factorial(1, num)
    }

    实际上就是每次将上次的结果传下去,这样就相当于每次再call一个func

    lazy模式

    func add(x int) int {
        fmt.Println("executing add")
        return x + x
    }
    
    func multiply(x int) int {
        fmt.Println("executing multiply")
        return x * x
    }
    
    func main() {
        fmt.Println(addOrMultiply(true, add, multiply, 4))
        fmt.Println(addOrMultiply(false, add, multiply, 4))
    }
    
    // This is now a higher-order-function hence evaluation of the functions are delayed in if-else
    func addOrMultiply(add bool, onAdd, onMultiply func(t int) int, t int) int {
        if add {
            return onAdd(t)
        }
        return onMultiply(t)
    }

    这样就可以避免性多调用一次add或者mutiply

    一个没有高级趣味的人。 email:hushui502@gmail.com
  • 相关阅读:
    Skype 1.4 for Linux 掉丢掉更新
    Skype 1.4 for Linux 失掉更新
    DiffMerge:可视化的文件相比与兼并东西
    Qt 4.3 公布揭晓
    Netscape Navigator 9 Beta 1 颁布
    Qtpfsgui:HDR 图片处置责罚器材
    Akregator 运用评测
    PenguinTV 3.0
    Exchange Server 2003备份
    Windows 编程[13] 菜单与菜单资源(二)
  • 原文地址:https://www.cnblogs.com/CherryTab/p/12404416.html
Copyright © 2011-2022 走看看