Golang中的函数式编程 |青训营笔记

53 阅读1分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天

函数式编程

函数式编程 vs 函数指针

  • 函数是一等公民:参数,变量,返回值都可以是函数
  • 高阶函数
  • 函数 -> 闭包

Go语言是通用语言

“正统”函数式编程(了解)

  • 不可变性:不能有状态,只有常量和函数
  • 函数只能有一个参数

函数与闭包

函数体内包含局部变量自由变量

Go语言闭包的应用

为函数实现接口**

 package main
 ​
 import (
     "bufio"
     "fmt"
     "io"
     "strings"
 )
 ​
 func fibonacci() intGen {
     a, b := 0, 1
     return func() int {
         a, b = b, a+b
         return a
     }
 }
 ​
 type intGen func() int
 ​
 func (g intGen) Read(p []byte) (n int, err error) {
     next := g()
     if next > 100000 {
         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() {
     f := fibonacci()
     printFileContents(f)
 ​
 }
复制代码
  • 更为自然,不需要修饰如何访问自由变量
  • 没有Lambda表达式,但是有匿名函数

错误处理

defer调用

  • 确保在函数结束时调用
  • 参数在defer语句时计算
  • defer列表为后进先出Stack

出错处理

 func writeFile(filename string) {
     file, err := os.OpenFile(
         filename, os.O_EXCL|os.O_CREATE, 0666)
     if err != nil {
         if PathError, ok := err.(*os.PathError); !ok {
             panic(err)
         } else {
             fmt.Println("%s, %s, %s\n", PathError.Op, PathError.Path, PathError.Err)
         }
         return
     }
 }
复制代码

自己生成错误

err = errors.New("This is a custom error")

测试

Debugging sucks; Testing Rocks!