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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM