109

Goを始めたばかりです。私のコードにはこれがたくさんあり始めています:

   if err != nil {
      //handle err
   }

またはこれ

  if err := rows.Scan(&some_column); err != nil {
      //handle err
  }

Goでエラーをチェックして処理するための良いイディオム/戦略/ベストプラクティスはありますか?

明確にするために編集:私は腹を立てたり、Goチームがより良いものを考え出すことを提案したりしていません. 私はそれを正しく行っているのか、それともコミュニティが思いついたテクニックを見逃していないのかを尋ねています. 皆さんありがとう。

4

11 に答える 11

31

この質問がされてから 6 か月後、Rob Pike はErrors are Valuesというタイトルのブログ投稿を書きました。

そこで彼は、OP によって提示された方法でプログラミングする必要はないと主張し、標準ライブラリ内で異なるパターンを使用するいくつかの場所について言及しています。

もちろん、エラー値を含む一般的なステートメントは、それが nil かどうかをテストすることですが、エラー値を使用して実行できることは他にも無数にあり、これらの他のことのいくつかを適用すると、定型文の多くを排除してプログラムを改善できます。これは、すべてのエラーが単純な if ステートメントでチェックされた場合に発生します。

...

この言語を使用して、エラー処理を簡素化します。

ただし、覚えておいてください。何をするにしても、常にエラーを確認してください。

よく読んでいます。

于 2015-03-04T04:25:58.373 に答える
22

どちらも慣用的なコードであるというjnmlの回答に同意し、次を追加します。

最初の例:

if err != nil {
      //handle err
}

複数の戻り値を扱う場合は、より慣用的です。例えば:

val, err := someFunc()
if err != nil {
      //handle err
}
//do stuff with val

err2 番目の例は、値のみを扱う場合の省略形です。これは、関数が のみを返す場合error、または 以外の戻り値を意図的に無視する場合に適用されますerror。例として、これは書き込まれたバイト数 (場合によっては不要な情報) とを返すReaderおよび関数と一緒に使用されることがあります。Writerinterror

if _, err := f.Read(file); err != nil {
      //handle err
}
//do stuff with f

2 番目の形式は、if 初期化ステートメントの使用と呼ばれます。

したがって、ベスト プラクティスに関しては、私の知る限り ( 「エラー」パッケージを使用して必要なときに新しいエラーを作成することを除いて)、Go のエラーについて知っておく必要のあるほとんどすべてをカバーしました!

編集:例外なしでは本当に生きていけないことがわかった場合はdefer、 , panic&recoverでそれらを模倣できます。

于 2013-06-06T14:42:32.717 に答える
1

業界のほとんどは、golang ドキュメントのエラー処理と Goに記載されている標準ルールに従っています。また、プロジェクトのドキュメント生成にも役立ちます。

于 2017-02-10T12:46:21.890 に答える
-1

同様のエラーのエラー処理コードをクリーンアップし (エラーはここで注意する必要がある値であるため)、エラーを処理するために渡されたエラーで呼び出す関数を作成できます。これで毎回「if err!=nil {}」と書く必要がなくなります。繰り返しますが、これはコードをクリーンアップするだけですが、それが慣用的な方法だとは思いません。

繰り返しますが、できるからといって、すべきであるとは限りません。

于 2015-06-04T10:07:19.020 に答える
-1

goerrでは、関数でエラーを処理できます

package main

import "github.com/goerr/goerr"
import "fmt"

func ok(err error) {
    if err != nil {
        goerr.Return(err)
        // returns the error from do_somethingN() to main()
        // sequence() is terminated
    }
}

func sequence() error {
    ok(do_something1())
    ok(do_something2())
    ok(do_something3())

    return nil /// 1,2,3 succeeded
}
func do_something1() error { return nil }
func do_something2() error { return fmt.Errorf("2") }
func do_something3() error {
    fmt.Println("DOING 3")
    return nil
}

func main() {
    err_do_something := goerr.OR1(sequence)

    // handle errors

    fmt.Println(err_do_something)
}
于 2015-07-18T20:17:50.740 に答える
-4

エラーを正確に制御したい場合、これは解決策ではないかもしれませんが、私にとっては、ほとんどの場合、エラーはショーストッパーです.

そのため、代わりに関数を使用します。

func Err(err error) {
    if err!=nil {
        fmt.Println("Oops", err)
        os.Exit(1)
    }
}

fi, err := os.Open("mmm.txt")
Err(err)
于 2015-06-16T21:07:36.927 に答える