<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                Go語言中閉包是引用了自由變量的函數,被引用的自由變量和函數一同存在,即使已經離開了自由變量的環境也不會被釋放或者刪除,在閉包中可以繼續使用這個自由變量,因此,簡單的說: ~~~ 函數 + 引用環境 = 閉包 ~~~ 同一個函數與不同引用環境組合,可以形成不同的實例,如下圖所示。 ![](https://img.kancloud.cn/9d/b7/9db74d4d3636b95cde7abe5517bd2bc2_512x205.jpg) 個函數類型就像結構體一樣,可以被實例化,函數本身不存儲任何信息,只有與引用環境結合后形成的閉包才具有“記憶性”,函數是編譯期靜態的概念,而閉包是運行期動態的概念。 #### 其它編程語言中的閉包 閉包(Closure)在某些編程語言中也被稱為 Lambda 表達式。 閉包對環境中變量的引用過程也可以被稱為“捕獲”,在[C++](http://c.biancheng.net/cplus/)11 標準中,捕獲有兩種類型,分別是引用和復制,可以改變引用的原值叫做“引用捕獲”,捕獲的過程值被復制到閉包中使用叫做“復制捕獲”。 在 Lua 語言中,將被捕獲的變量起了一個名字叫做 Upvalue,因為捕獲過程總是對閉包上方定義過的自由變量進行引用。 閉包在各種語言中的實現也是不盡相同的,在 Lua 語言中,無論閉包還是函數都屬于 Prototype 概念,被捕獲的變量以 Upvalue 的形式引用到閉包中。 C++ 與[C#](http://c.biancheng.net/csharp/)中為閉包創建了一個類,而被捕獲的變量在編譯時放到類中的成員中,閉包在訪問被捕獲的變量時,實際上訪問的是閉包隱藏類的成員。 ## 在閉包內部修改引用的變量 閉包對它作用域上部的變量可以進行修改,修改引用的變量會對變量進行實際修改,通過下面的例子來理解: ~~~ // 準備一個字符串str := "hello world"// 創建一個匿名函數foo := func() { // 匿名函數中訪問str str = "hello dude"}// 調用匿名函數foo() ~~~ 代碼說明如下: * 第 2 行,準備一個字符串用于修改。 * 第 5 行,創建一個匿名函數。 * 第 8 行,在匿名函數中并沒有定義 str,str 的定義在匿名函數之前,此時,str 就被引用到了匿名函數中形成了閉包。 * 第 12 行,執行閉包,此時 str 發生修改,變為 hello dude。 代碼輸出: ``` hello dude ``` ## 示例:閉包的記憶效應 被捕獲到閉包中的變量讓閉包本身擁有了記憶效應,閉包中的邏輯可以修改閉包捕獲的變量,變量會跟隨閉包生命期一直存在,閉包本身就如同變量一樣擁有了記憶效應。 累加器的實現: ~~~ package main import "fmt" func main() { // 創建一個累加器 accumulator := Accumulate(1) // 累加1并打印 fmt.Println(accumulator()) fmt.Println(accumulator()) // 打印累加器的函數地址 fmt.Printf("%p\n", &accumulator) // 創建一個累加器,初始值為1 accumulator2 := Accumulate(10) // 累加1并打印 fmt.Println(accumulator2()) // 打印累加器的函數地址 fmt.Printf("%p\n", &accumulator2) } // Accumulate 提供一個值,每次調用函數會指定對值進行累加 func Accumulate(value int) func() int { // 返回一個閉包 return func() int { // 累加 value++ return value } } ~~~ ## 示例:閉包實現生成器 閉包的記憶效應被用于實現類似于[設計模式](http://c.biancheng.net/design_pattern/)中工廠模式的生成器,下面的例子展示了創建一個玩家生成器的過程。 玩家生成器的實現: ~~~ package main import "fmt" func main() { // 創建一個玩家生成器 generator := playerGen("high noon") name, hp := generator() fmt.Println(name, hp) } // 創建一個玩家生成器,輸入名稱,輸出生成器 func playerGen(name string) func() (string, int) { // 血量一直都為159 hp := 150 return func() (string, int) { return name, hp } } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看