<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ### 閉包 閉包是由函數及其相關引用環境組合而成的實體(即:閉包=函數+引用環境) “官方”的解釋是:所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分 javascript閉包示例: ~~~ <script> function a(){ var i=0; function b(){ console.log(++i); document.write("<h1>"+i+"</h1>"); } return b; } $(function(){ var c=a(); c(); c(); c(); //a(); //不會有信息輸出 document.write("<h1>=============</h1>"); var c2=a(); c2(); c2(); }); </script> ~~~ 這段代碼有兩個特點: 函數b嵌套在函數a內部 函數a返回函數b 這樣在執行完var c=a()后,變量c實際上是指向了函數b(),再執行函數c()后就會顯示i的值,第一次為1,第二次為2,第三次為3,以此類推。 其實,這段代碼就創建了一個閉包。因為函數a()外的變量c引用了函數a()內的函數b(),就是說: 當函數a()的內部函數b()被函數a()外的一個變量引用的時候,就創建了一個閉包。 在上面的例子中,由于閉包的存在使得函數a()返回后,a中的i始終存在,這樣每次執行c(),i都是自加1后的值。 從上面可以看出閉包的作用就是在a()執行完并返回后,閉包使得Javascript的垃圾回收機制GC不會收回a()所占用的資源,因為a()的內部函數b()的執行需要依賴a()中的變量i。 在給定函數被多次調用的過程中,這些私有變量能夠保持其持久性。變量的作用域僅限于包含它們的函數,因此無法從其它程序代碼部分進行訪問。不過,變量的生存期是可以很長,在一次函數調用期間所創建所生成的值在下次函數調用時仍然存在。正因為這一特點,閉包可以用來完成信息隱藏,并進而應用于需要狀態表達的某些編程范型中。 下面來想象另一種情況,如果a()返回的不是函數b(),情況就完全不同了。因為a()執行完后,b()沒有被返回給a()的外界,只是被a()所引用,而此時a()也只會被b()引 用,因此函數a()和b()互相引用但又不被外界打擾(被外界引用),函數a和b就會被GC回收。所以直接調用a();是頁面并沒有信息輸出。 下面來說閉包的另一要素引用環境。c()跟c2()引用的是不同的環境,在調用i++時修改的不是同一個i,因此兩次的輸出都是1。函數a()每進入一次,就形成了一個新的環境,對應的閉包中,函數都是同一個函數,環境卻是引用不同的環境。這和c()和c()的調用順序都是無關的。 ### Go的閉包 Go語言是支持閉包的,這里只是簡單地講一下在Go語言中閉包是如何實現的。 下面我來將之前的JavaScript的閉包例子用Go來實現。 ~~~ package main import ( "fmt" ) func a() func() int { i := 0 b := func() int { i++ fmt.Println(i) return i } return b } func main() { c := a() c() c() c() a() //不會輸出i } ~~~ 輸出結果: ~~~ 1 2 3 ~~~ 可以發現,輸出和之前的JavaScript的代碼是一致的。具體的原因和上面的也是一樣的,這說明Go語言是支持閉包的。 閉包復制的是原對象指針,這就很容易解釋延遲引用現象。 ~~~ package main import "fmt" func test() func() { x := 100 fmt.Printf("x (%p) = %d\n", &x, x) return func() { fmt.Printf("x (%p) = %d\n", &x, x) } } func main() { f := test() f() } ~~~ 輸出: ~~~ x (0xc42007c008) = 100 x (0xc42007c008) = 100 ~~~ 在匯編層 ,test 實際返回的是 FuncVal 對象,其中包含了匿名函數地址、閉包對象指針。當調 匿名函數時,只需以某個寄存器傳遞該對象即可。 ~~~ FuncVal { func_address, closure_var_pointer ... } ~~~ 外部引用函數參數局部變量 ~~~ package main import "fmt" // 外部引用函數參數局部變量 func add(base int) func(int) int { return func(i int) int { base += i return base } } func main() { tmp1 := add(10) fmt.Println(tmp1(1), tmp1(2)) // 此時tmp1和tmp2不是一個實體了 tmp2 := add(100) fmt.Println(tmp2(1), tmp2(2)) } ~~~ 返回2個閉包 ~~~ package main import "fmt" // 返回2個函數類型的返回值 func test01(base int) (func(int) int, func(int) int) { // 定義2個函數,并返回 // 相加 add := func(i int) int { base += i return base } // 相減 sub := func(i int) int { base -= i return base } // 返回 return add, sub } func main() { f1, f2 := test01(10) // base一直是沒有消 fmt.Println(f1(1), f2(2)) // 此時base是9 fmt.Println(f1(3), f2(4)) } ~~~
                  <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>

                              哎呀哎呀视频在线观看