函數一等公民,在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
