5. 函數語言程式設計
阿新 • • 發佈:2018-12-01
一. 函數語言程式設計
函數語言程式設計 VS 函式指標
- 函式是一等公民: 引數, 變數, 返回值都可以是函式
- 高階函式
- 函式 -> 閉包
"正統" 函數語言程式設計
- 不可變性: 不能有狀態, 只有常量和函式
- 函式只能有一個引數
- go語言程式設計時, 上述嚴格的規定 不是必須的
閉包實現累加器
package main import "fmt" // 閉包 func adder() func(int) int { sum := 0 return func(v int) int { sum += v return sum } } // 正統函數語言程式設計 閉包 type iAdder func(int) (int, iAdder) // 遞迴 func adder2(base int) iAdder { return func(v int) (int, iAdder) { return base + v, adder2(base + v) } } func main() { a1 := adder() for i := 0; i < 10; i++ { fmt.Printf("0 + 1 + ... + %d = %d\n", i, a1(i)) } a := adder2(0) for i := 0; i < 10; i++ { var s int s, a = a(i) fmt.Printf("0 + 1 + ... + %d = %d\n", i, s) } }
二. 函數語言程式設計例子
斐波那契數列
package main import "fmt" // 1, 1, 2, 3, 5, 8, 13, ... 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()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) fmt.Println(f()) }
為函式生成介面
- 使斐波那契函式,實現reader介面。 這樣就可以像讀檔案那樣去列印它
package main import ( "bufio" "fmt" "io" "strings" "learngo/lang/functional/fib" ) type intGen func() int // 斐波那契 函式介面 func (g intGen) Read( p []byte) (n int, err error) { next := g() if next > 10000 { // 大於10000 讓函式結束, 即檔案讀到頭了 return 0, io.EOF } s := fmt.Sprintf("%d\n", next) // TODO: incorrect if p is too small! return strings.NewReader(s).Read(p) } func printFileContents(reader io.Reader) { scanner := bufio.NewScanner(reader) for scanner.Scan() { fmt.Println(scanner.Text()) } } func main() { var f intGen = fib.Fibonacci() printFileContents(f) }