go语言编程之——闭包(介绍定义+两种写法)

一 、定义:

闭包:要有一个需要保护的局部变量+一个匿名函数

二、闭包的两种写法:

1. 在主函数之外定义一个闭包函数,闭包函数的格式为:

  func  函数名  func() int{

      res = func()  int{

   ......

}  

return res

}

举例一:

package main

import "fmt"

func main() {
    //主函数始终存在对add2的引用,因此只要主函数没被关闭,gc就不会回收add2中的s
   res := add2() //此时,res的实质是函数 res = func(int)int

   fmt.Printf("res = %T", res)

   for i := 0; i < 10;i++  {
      fmt.Printf("i=%d ", i)
      sum := res(i) //res既然是个函数,那么传入对应的参数即可。
      fmt.Println(sum)


   }

}

func add2() func(int)int{
   s := 0
   res := func(i int) int{
      s += i
      return s
   }
   return res
}

 

举例二:

package main

import "fmt"

func main() {



   res := counter()
   //先看看res的类型
   fmt.Printf("%T \n", res) //func() int
   //再看看res的值
   fmt.Printf("res=%d \n", res)  //res=4771872
   //最后看看res()的值
   fmt.Printf("res()=%d \n",res())  //res()=1  注意思考这里为什么是1
   fmt.Println("res():", res()) //res()=2  注意思考这里为什么是2
   fmt.Println("res():", res())//res()=3  注意思考这里为什么是3
    fmt.Println("res():", res())//res()=4  注意思考这里为什么是4

     //现在再赋给一个变量res2,注意观察它的内存地址与值
   fmt.Printf("res=%d \n", res)  //res=4771872
   //最后看看res()的值
   fmt.Printf("res()=%d \n",res())  //res()=5  注意思考这里为什么是1
   fmt.Println("res():", res()) //res()=6 注意思考这里为什么是2

   res2 := counter()
   fmt.Printf("res2:",res2)  //4774192
   fmt.Println("res2():" , res2())
   fmt.Println("res2():" , res2())
   fmt.Println("res2():" , res2())
}

//用闭包实现counter功能,并注意观察各类类型
   //闭包的步骤:1. 在函数中写一个匿名函数“func() 返回值类型{}”,并用一个变量接受
   //            2. 返回匿名函数
   //            3. 在主方法中用变量接收函数counter.其实也就是接收闭包函数
func counter() func() int{
   i := 0
   res  := func() int{
      i += 1
      return i
   }
   //注意观察这里的res其实是个地址
   fmt.Printf("Counter中的res=%d \n" , res) //Counter中的res=4771872
   return res
}

2. 闭包的另一种省略写法:

 直接在主函数中定义一个闭包:

res := func() (func() int){

return func() int{

}

}()

举例一:

package main

import "fmt"

func main() {

   /**  闭包另一种省略写法
       1. 定义一个匿名闭包函数,这个闭包函数是没有参数的,但一定有返回值,返回一个匿名函数
       2. 定义内部的匿名函数,内部的匿名函数一定要与返回的匿名函数类型一致
       3. 返回刚刚定义的匿名函数
       4. 匿名函数的用法:在声明的时候就调用必须在后面加上()

     综上所述,闭包写法为:
      res := func() (func() int){
   }()
    */
   res := func () (func() int){
      i := 10
      return func() int{
         i++
         return i
      }
   }()

   fmt.Println(res) //这样输出来的是地址
   fmt.Println(res()) //res()代表运行闭包中的函数
   
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章