Golang での例外処理

Go语言进阶学习
Go语言进阶学习転載
2023-07-24 15:20:521410ブラウズ
<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">Golang</span> には、以前の記事で述べたように多くの利点がありますが、Gopher が批判した欠点も数多くあります。特に、Yes #########エラー処理#########。 <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"></span>エラーと例外について説明する前に、2 つの概念について説明します。 エラー処理
: エラーはビジネスの一部であり、予見できます。 。

例外処理

: ビジネスの一部ではありません。予期せぬものです。 エラー処理

まずサンプル コードを見てください:

file, err := os.Open("/usr/local/test.txt")
Golang は上記のコードのエラー処理方法を公式に推奨しており、

を推奨しています。 err

は戻り値の最後に置かれます。日常のコーディングでも

func<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"> を定義するために、このようなルールに従う必要があります。 </span><blockquote style="box-sizing: border-box;margin-top: 1em;margin-bottom: 1.2em;padding: 15px 15px 15px 1rem;color: rgb(129, 145, 152);border-left-width: 6px;border-left-color: rgb(220, 230, 240);font-size: 14px;line-height: 22px;background: rgb(242, 247, 251);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;white-space: normal;"><p style="box-sizing: border-box;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);">在Gopher间流传着这样一个笑话:一半时间在编写代码,一半时间在写错误处理。</p></blockquote> <p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 16px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;">示例代码:</p><pre class="brush:php;toolbar:false;">func Open(name string) (*File, error) { return OpenFile(name, O_RDONLY, 0) }</pre><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 16px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;">但通常不是每个方法都需要处理 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);line-height: 18px;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">err</span>,可以适当的将 <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">err</span>返回给上层函数,由上层函数统一打印或者处理错误。例如:<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">http</span> 路由中的错误可以在路由返回数据前处理,将错误信息和错误码格式化后返回给 <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">Client</span>

例外処理

Golang の例外処理は非常に独特で、<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">defer</span> <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">err</span> ## が必要です。 #recover<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"></span>()<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"></span> この 3 つは一緒に使用されますが、Java に必要なのは try<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"></span>{<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"></span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"># のみです。 ##}</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">Catch</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">()</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;"> を実行できます。サンプル コードを見てみましょう: </span><pre class="brush:php;toolbar:false;">package main import ( &quot;fmt&quot; ) func main() { test() } func test() { defer func() { if e := recover(); e != nil { fmt.Println(&quot;Worng!&quot;) } }() panic(&quot;panic&quot;) }</pre><p style="box-sizing: border-box;margin-top: 15px;margin-bottom: 15px;font-size: 16px;white-space: pre-line;line-height: 30px;color: rgb(74, 74, 74);font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif;">如上代码在 <code style="box-sizing: border-box;background: rgb(243, 241, 241);color: rgb(88, 88, 88);line-height: 18px;"><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">test</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">()</span>函数及其子函数中如果发生panic的错误,就会打印:

Worng!

代码封装

当然,在每个方法最上面写这么一大堆冗余的代码是很不优雅的,也不符合面向对象的特性:<span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">封装</span>,于是便可以封装成 <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">CoverErrorMessage</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">()</span> ,而 <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">test</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">()</span>函数改写如下:

package main

import (
    "fmt"
)

func main() {
    test()
}

func test()  {
    defer tools.CoverErrorMessage()
    panic("panic")
}

func  CoverErrorMessage() {
   if message := recover(); message != nil {
      var err error
      switch x := message.(type) {
      case string:
         err = errors.New(x)
      case error:
         err = x
      default:
         err = errors.New("Unknow panic")
      }
      Logger.Error("Recovered panic error : ",err)
   }
}

defer 处理异常时只能将 <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">recover</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">()</span>写在第一层函数中,否则将无法 <span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">recover</span><span style="box-sizing: border-box;background-image: initial;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;display: inline-block;padding-right: 2px;padding-left: 2px;font-size: 14px;">()</span>到panic错误

以上がGolang での例外処理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はGo语言进阶学习で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。