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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                Golang 沒有結構化異常,使用 panic 拋出錯誤,recover 捕獲錯誤。 異常的使用場景簡單描述:Go中可以拋出一個panic的異常,然后在defer中通過recover捕獲這個異常,然后正常處理。 panic: 1、內置函數 2、假如函數F中書寫了panic語句,會終止其后要執行的代碼,在panic所在函數F內如果存在要執行的defer函數列表,按照defer的逆序執行 3、返回函數F的調用者G,在G中,調用函數F語句之后的代碼不會執行,假如函數G中存在要執行的defer函數列表,按照defer的逆序執行 4、直到goroutine整個退出,并報告錯誤 recover: 1、內置函數 2、用來控制一個goroutine的panicking行為,捕獲panic,從而影響應用的行為 3、一般的調用建議 a). 在defer函數中,通過recever來終止一個goroutine的panicking過程,從而恢復正常代碼的執行 b). 可以獲取通過panic傳遞的error 注意: 1.利用recover處理panic指令,defer 必須放在 panic 之前定義,另外 recover 只有在 defer 調用的函數中才有效。否則當panic時,recover無法捕獲到panic,無法防止panic擴散。 2.recover 處理異常后,邏輯并不會恢復到 panic 那個點去,函數跑到 defer 之后的那個點。 3.多個 defer 會形成 defer 棧,后定義的 defer 語句會被最先調用。 ~~~ package main func main() { test() } func test() { defer func() { if err := recover(); err != nil { println(err.(string)) // 將 interface{} 轉型為具體類型。 } }() panic("panic error!") } ~~~ 輸出結果: ~~~ panic error! ~~~ 由于 panic、recover 參數類型為 interface{},因此可拋出任何類型對象。 ~~~ func panic(v interface{}) func recover() interface{} ~~~ 向已關閉的通道發送數據會引發panic ~~~ package main import ( "fmt" ) func main() { defer func() { if err := recover(); err != nil { fmt.Println(err) } }() var ch chan int = make(chan int, 10) close(ch) ch <- 1 } ~~~ 輸出結果: ~~~ send on closed channel ~~~ 延遲調用中引發的錯誤,可被后續延遲調用捕獲,但僅最后一個錯誤可被捕獲。 ~~~ package main import "fmt" func test() { defer func() { fmt.Println(recover()) }() defer func() { panic("defer panic") }() panic("test panic") } func main() { test() } ~~~ 輸出: ~~~ defer panic ~~~ 捕獲函數 recover 只有在延遲調用內直接調用才會終止錯誤,否則總是返回 nil。任何未捕獲的錯誤都會沿調用堆棧向外傳遞。 ~~~ package main import "fmt" func test() { defer func() { fmt.Println(recover()) //有效 }() defer recover() //無效! defer fmt.Println(recover()) //無效! defer func() { func() { println("defer inner") recover() //無效! }() }() panic("test panic") } func main() { test() } ~~~ 輸出: ~~~ defer inner <nil> test panic ~~~ 使用延遲匿名函數或下面這樣都是有效的。 ~~~ package main import ( "fmt" ) func except() { fmt.Println(recover()) } func test() { defer except() panic("test panic") } func main() { test() } ~~~ 輸出結果: ~~~ test panic ~~~ 如果需要保護代碼 段,可將代碼塊重構成匿名函數,如此可確保后續代碼被執 。 ~~~ package main import "fmt" func test(x, y int) { var z int func() { defer func() { if recover() != nil { z = 0 } }() panic("test panic") z = x / y return }() fmt.Printf("x / y = %d\n", z) } func main() { test(2, 1) } ~~~ 輸出結果: ~~~ x / y = 0 ~~~ 除用 panic 引發中斷性錯誤外,還可返回 error 類型錯誤對象來表示函數調用狀態。 ~~~ type error interface { Error() string } ~~~ 標準庫 errors.New 和 fmt.Errorf 函數用于創建實現 error 接口的錯誤對象。通過判斷錯誤對象實例來確定具體錯誤類型。 ~~~ package main import ( "errors" "fmt" ) var ErrDivByZero = errors.New("division by zero") func div(x, y int) (int, error) { if y == 0 { return 0, ErrDivByZero } return x / y, nil } func main() { defer func() { fmt.Println(recover()) }() switch z, err := div(10, 0); err { case nil: println(z) case ErrDivByZero: panic(err) } } ~~~ 輸出結果: ~~~ division by zero ~~~ Go實現類似 try catch 的異常處理 ~~~ package main import "fmt" func Try(fun func(), handler func(interface{})) { defer func() { if err := recover(); err != nil { handler(err) } }() fun() } func main() { Try(func() { panic("test panic") }, func(err interface{}) { fmt.Println(err) }) } ~~~ 輸出結果: ~~~ test panic ~~~ 如何區別使用 panic 和 error 兩種方式? 慣例是:導致關鍵流程出現不可修復性錯誤的使用 panic,其他使用 error。
                  <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>

                              哎呀哎呀视频在线观看