<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 功能強大 支持多語言、二開方便! 廣告
                [TOC] ## 引入 `foo` 函數功能已經開發好了,并且運行一切正常。現在有個小需求就是要統計該函數被調用的次數。 ```go package main import fmt var count int func foo() { fmt.Println("foo函數功能") count++ } func main() { foo() foo() fmt.Printf("foo函數被調用的次數: %d", count) } // 運行結果: // foo函數功能 // foo函數功能 // foo函數被調用的次數: 2 ``` 以上的代碼可以實現到需求,但是不是很完美。原因其一,添加全局變量,會帶來的風險是污染全局變量。其二,改動原來正常運行的函數。 基于以上兩個原因,可以改進成閉包函數。 ## 閉包函數 閉包的作用: - 可以讓一個變量常駐內存 - 可以讓一個變量不污染全局 閉包可以理解成 “定義在一個函數內部的函數,內部函數(匿名函數)引用非自己作用域的變量”。閉包是匿名函數的應用。 - 閉包是指有權訪問另一個函數作用域中的變量的函數 - 創建閉包的常見的方式就是在一個函數內部創建另一個函數,通過另一個函數訪問這個函數的局部變量 >[warning] 注意:由于閉包里作用域返回的局部變量資源不會被立刻銷毀,所以可能會占用更多的內存,過度使用閉包會導致性能下降,建議在非常有必要的時候才使用閉包。 以下代碼解決上述說到的第一個問題(污染全局變量)。 ```go package main import fmt func foo() func() int8 { var count int8 return func() int8 { fmt.Println("foo函數功能") count++ return count } } func main() { f := foo() f() count := f() fmt.Printf("foo函數被調用的次數: %d\n", count) } // 運行結果: // foo函數功能 // foo函數功能 // foo函數被調用的次數: 2 ``` >[info] 以上代碼,foo函數不是閉包函數。而 `f` 函數則是閉包函數。其中 `f` 函數體在 foo 函數的匿名函數函數體。函數 `f` 調用 foo 函數的 count 變量。即是**閉包函數**。 以下代碼是通過上面改良版本,解決修改原有函數體內容。該函數可以統計相同類型的函數調用次數 ```go package main import fmt func foo() { fmt.Println("foo函數功能") } func bar() { fmt.Println("bar函數功能") } func funcCounter(f func()) func() int8 { var count int8 return func() int8 { f() count++ return count } } func main() { foo := funcCounter(foo) foo() fooCount := foo() fmt.Printf("foo函數被調用的次數: %d\n", fooCount) bar := funcCounter(bar) barCount := bar() fmt.Printf("bar函數被調用的次數: %d\n", barCount) } // 運行結果: // foo函數功能 // foo函數功能 // foo函數被調用的次數: 2 // bar函數功能 // bar函數被調用的次數: 1 ``` >[info] 以上代碼,main 函數的賦值 foo 、 bar 函數是閉包函數,兩個函數體在 funcCounter 的匿名函數體里面。且匿名函數調用了 funcCounter 函數的 count 變量。即調用 funcCounter 函數,返回的函數即為閉包函數。 funcCounter 函數叫做裝飾器函數。 由此可得,裝飾器函數是閉包函數的應用。 ## 閉包相關示例 示例1 ```go /* 計數器(1) 調用一次,則累加一。 */ func counter() func() { var i int return func() { i++ fmt.Printf("i: %v\n", i) } } func main() { f1 := counter() f1() f1() f1() } // 運行結果: // i: 1 // i: 2 // i: 3 ``` 示例2 ```go /* 自定義初始化值累加器 調用一次,則累加一。 */ func counterInitValue(i int) func() int { return func() int { i++ return i } } func main() { i := 5 f2 := counterInitValue(i) i = f2() i = f2() i = f2() fmt.Printf("f2-> i: %v\n", i) } // 運行結果: // f2-> i: 8 ``` 示例3 ```go /* 文件擴展名 判斷文件是否為指定擴展名。如果不是的話添加,否則直接返回文件名。 */ func fileExtension(suffix string) func(string) string { return func(name string) string { if strings.HasSuffix(name, suffix) { return name } else { return name + suffix } } } func main() { f3 := fileExtension(".json") filename1 := f3("test") filename2 := f3("config.json") fmt.Printf("filename: %s, filename: %s\n", filename1, filename2) } // 運行結果: // filename: test.json, filename: config.json ``` 示例4 ```go /* 計算器 兩數相加或相減函數 */ func calc(x int, y int) (func() int, func() int) { add := func() int { return x + y } sub := func() int { return x - y } return add, sub } func main() { add, sub := calc(10, 5) fmt.Printf("add(): %v\n", add()) fmt.Printf("sub(): %v\n", sub()) } // 運行結果: // add(): 15 // sub(): 5 ```
                  <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>

                              哎呀哎呀视频在线观看