golang错误处理之error
golang中没有try/catch这样的异常处理机制,只能依靠返回值来做状态是否出错判断(当然它有个panic/recover机制,但一般只处理意想不到的错误)。对于函数的返回值,惯例是最后一个参数返回error对象,来表示函数运行的状态。
如:
- n, err := func()
- if err != nil {
- ...//process error
- }
- if n, err := func(); err != nil {
- ...//process error
- }
error对象可以由errors.New()或fmt.Errorf()构造。
如:
- var dividedErr = errors.New("Cant divided by 0")
- err := fmt.Errorf("%d cant divided by 0", arg)
我们先来看看error到底是什么类型。
error在标准库中被定义为一个接口类型,该接口只有一个Error()方法:
- type error interface {
- Error() string
- }
我们可以创建一个结构体,并实现Error()方法,就能根据自己的意愿构造error对象了。
如:
<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>type division struct {</li><li> arg int</li><li> str string</li><li>}</li><li></li><li>func (e *division) Error() string {</li><li> return fmt.Sprintf("%d %s", e.arg, e.str)</li><li>}</li><li></li><li>func divideCheck(arg1, arg2 int) (error) {</li><li> if arg2 == 0 {</li><li> return &division{arg1, "can't divided by 0"}</li><li> }</li><li> return nil</li><li>}</li></ol>
再来看一个例子,检查一组数据中是否有不能除(即除数为0)的情况,如果有则返回出错。
代码如下:
<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>package main</li><li></li><li>import "fmt"</li><li></li><li>func divideCheck(arg1, arg2 int) (error) {</li><li> if arg2 == 0 {</li><li> return fmt.Errorf("%d can't divided by 0", arg1)</li><li> }</li><li> return nil</li><li>}</li><li></li><li>func main() {</li><li> var err error</li><li></li><li> err = divideCheck(4, 2)</li><li> if err != nil {</li><li> fmt.Println(err)</li><li> return</li><li> }</li><li></li><li> err = divideCheck(8, 0)</li><li> if err != nil {</li><li> fmt.Println(err)</li><li> return</li><li> }</li><li>}</li></ol>
我们实现了这个功能,但是这样的代码非常不优雅,每执行一次函数调用都至少要用3行来做错误处理。
下面来优化一下。我们需要实现的功能是,只要有一个数不能除,就返回出错。那么只需要把每次检查后的状态存储到内部状态变量里,在全部处理完成后再检查这个变量就行了。
代码如下:
<ol style="margin:0 1px 0 0px;padding-left:40px;" start="1" class="dp-css"><li>package main</li><li></li><li>import "fmt"</li><li></li><li>type division struct {</li><li> err error</li><li>}</li><li></li><li>func (this *division)DivideCheck(arg1, arg2 int) {</li><li> if this.err != nil {</li><li> return</li><li> }</li><li> if arg2 == 0 {</li><li> this.err = fmt.Errorf("%d can't divided by 0", arg1)</li><li> return</li><li> }</li><li>}</li><li></li><li>func (this *division)Err() error {</li><li> return this.err</li><li>}</li><li></li><li>func main() {</li><li> d := new(division)</li><li> d.DivideCheck(4, 2)</li><li> d.DivideCheck(8, 0)</li><li> if d.Err() != nil {</li><li> fmt.Println(d.Err())</li><li> }</li><li>}</li></ol>这么做代码就优雅多了,并且在每次检查前都判断内部状态是否已经出错,出错就马上返回,几乎没有性能损失。
golang的错误处理是经常被诟病的地方,但如果懂得以go的方式编程,还是可以做的挺优雅的~
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事
R.E.P.O.説明されたエネルギー結晶と彼らが何をするか(黄色のクリスタル)
3週間前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最高のグラフィック設定
3週間前By尊渡假赌尊渡假赌尊渡假赌
アサシンのクリードシャドウズ:シーシェルリドルソリューション
2週間前ByDDD
R.E.P.O.誰も聞こえない場合はオーディオを修正する方法
3週間前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:Myriseのすべてのロックを解除する方法
3週間前By尊渡假赌尊渡假赌尊渡假赌

ホットツール

EditPlus 中国語クラック版
サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

メモ帳++7.3.1
使いやすく無料のコードエディター

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ZendStudio 13.5.1 Mac
強力な PHP 統合開発環境
