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()代表運行閉包中的函數
   
}

 

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