1.累加器
func AddUpper() myFun {
   //闭包:返回的函数与这个函数引用到函数外的变量n形成一个整体,共同生成闭包,反复调用f1函数即AddUpper函数,n只初始化一次,所以返回的值的累加的。
   //闭包可以理解成一个类,函数是操作,n是字段。函数和它使用到的n构成闭包。
   //匿名函数引用了函数外部的变量n,把这个n叫做自由变量。闭包的实现确保只要闭包还被使用,那么被闭包引用的变量会一直存在。
   //根据闭包的概念,这个n变量不会被销毁,一直存在,相当于全局变量是常驻内存,但是这个变量又不会污染全局,只是存在在相应的环境f1,f2里。
   //即使已经离开了自由变量的环境也不会被释放或者删除,在闭包中可以继续使用这个自由变量,因此,简单的说:函数 + 引用环境 = 闭包
   //同一个函数与不同引用环境f1,f2组合,可以形成不同的实例。
   var n int = 10
   return func(x int) int {
      n = n + x
      return n
   }
}
func main() {
   f1 := AddUpper()
   f2 := AddUpper()
   fmt.Println(f1(1)) //11
   fmt.Println(f1(2)) //13,累计了上面的f1(1)
   fmt.Println(f2(1)) //11
   fmt.Println(f2(2)) //13,累计了上面的f2(1)
}
//2.传入字符串,不以.jpg结尾的使其输出以.jpg结尾,原来以.jpg结尾的原样输出。
//使用闭包,将后缀.jpg只输入一次就保存下来,供后续使用。
package main
import (
   "fmt"
   "strings"
)
func makeSuffix(suffix string) func(string) string {
   //返回的匿名函数和外部变量suffix组成了闭包
   return func(s string) string {
      res := strings.HasSuffix(s, suffix)
      if res != true {
         return s + suffix
      }
      return s
   }
}
func main() {
   //f1接收的makeSuffix的返回值,即makeSuffix的返回函数func(string) string
   //因为要设置变量.jpg为固定变量,而输入变量hello为不定变量,所以用了闭包函数,使.jpg为自由变量不会消失。
   //使用闭包,只需要传入一次.jpg,就会将这个值保存下来,后面反复使用
   f1 := makeSuffix(".jpg")
   //f1("hello")为对makeSuffix的返回函数赋值即为设置func("hello") string
   res1 := f1("hello")
   res2 := f1("hello.jpg")
   fmt.Println(res1)
   fmt.Println(res2)
}