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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                每當函數返回時,我們應該檢查是否有錯誤發生:但是這會導致重復乏味的代碼。結合 defer/panic/recover 機制和閉包可以得到一個我們馬上要討論的更加優雅的模式。不過這個模式只有當所有的函數都是同一種簽名時可用,這樣就有相當大的限制。一個很好的使用它的例子是 web 應用,所有的處理函數都是下面這樣: ~~~ func handler1(w http.ResponseWriter, r *http.Request) { ... } ~~~ 假設所有的函數都有這樣的簽名: ~~~ func f(a type1, b type2) ~~~ 參數的數量和類型是不相關的。 我們給這個類型一個名字: ~~~ fType1 = func f(a type1, b type2) ~~~ 在我們的模式中使用了兩個幫助函數: 1)check:這是用來檢查是否有錯誤和 panic 發生的函數: ~~~ func check(err error) { if err != nil { panic(err) } } ~~~ 2)errorhandler:這是一個包裝函數。接收一個 fType1 類型的函數 fn 并返回一個調用 fn 的函數。里面就包含有 defer/recover 機制,這在?[13.3 節](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/13.3.md)中有相應描述。 ~~~ func errorHandler(fn fType1) fType1 { return func(a type1, b type2) { defer func() { if e, ok := recover().(error); ok { log.Printf(“run time panic: %v”, err) } }() fn(a, b) } } ~~~ 當錯誤發生時會 recover 并打印在日志中;除了簡單的打印,應用也可以用 template 包(參見?[15.7 節](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/15.7.md))為用戶生成自定義的輸出。check() 函數會在所有的被調函數中調用,像這樣: ~~~ func f1(a type1, b type2) { ... f, _, err := // call function/method check(err) t, err := // call function/method check(err) _, err2 := // call function/method check(err2) ... } ~~~ 通過這種機制,所有的錯誤都會被 recover,并且調用函數后的錯誤檢查代碼也被簡化為調用 check(err) 即可。在這種模式下,不同的錯誤處理必須對應不同的函數類型;它們(錯誤處理)可能被隱藏在錯誤處理包內部。可選的更加通用的方式是用一個空接口類型的切片作為參數和返回值。 我們會在?[15.5 節](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/15.5.md)的 web 應用中使用這種模式。 練習 **練習 13.1**:[recover_dividebyzero.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/exercises/chapter_13/recover_divbyzero.go) 用示例 13.3 中的編碼模式通過整數除以 0 觸發一個運行時 panic。 **練習 13.2**:[panic_defer.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/exercises/chapter_13/panic_defer.go) 閱讀下面的完整程序。不要執行它,寫出程序的輸出結果。然后編譯執行并驗證你的預想。 ~~~ // panic_defer.go package main import "fmt" func main() { f() fmt.Println("Returned normally from f.") } func f() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) } }() fmt.Println("Calling g.") g(0) fmt.Println("Returned normally from g.") } func g(i int) { if i > 3 { fmt.Println("Panicking!") panic(fmt.Sprintf("%v", i)) } defer fmt.Println("Defer in g", i) fmt.Println("Printing in g", i) g(i + 1) } /* Output: Calling g. Printing in g 0 Printing in g 1 Printing in g 2 Printing in g 3 Panicking! Defer in g 3 Defer in g 2 Defer in g 1 Defer in g 0 Recovered in f 4 Returned normally from f. */ ~~~ **練習 13.3**:[panic_defer_convint.go](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/exercises/chapter_13/panic_defer_convint.go) 寫一個 ConvertInt64ToInt 函數把 int64 值轉換為 int 值,如果發生錯誤(提示:參見?[4.5.2.1 節](https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/04.5.md#4521-%E6%95%B4%E5%9E%8B-int-%E5%92%8C%E6%B5%AE%E7%82%B9%E5%9E%8B-float))就 panic。然后在函數 IntFromInt64 中調用這個函數并 recover,返回一個整數和一個錯誤。請測試這個函數!
                  <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>

                              哎呀哎呀视频在线观看