error is nil repetition のチェックをしないようにするか?
質問
私は現在goを学んでおり、私のコードのいくつかは次のようになります。
a, err := doA()
if err != nil {
return nil, err
}
b, err := doB(a)
if err != nil {
return nil, err
}
c, err := doC(b)
if err != nil {
return nil, err
}
... and so on ...
これは、エラーチェックがほとんどの行を占めているため、私にはちょっと間違っているように見えます。エラー処理を行うためのより良い方法はありますか?私はおそらくいくつかのリファクタリングでこれを避けることができますか?
UPDATEです。 たくさんのご回答ありがとうございました。私の例では、doBはaに依存し、doCはbに依存し、といった具合になることに注意してください。したがって、ほとんどの提案されたリファクタリングは、このケースでは動作しません。他の提案はありますか?
どのように解決するのですか?
これはよくある苦情ですが、これにはいくつかの回答があります。
ここでは、よくあるものをいくつか紹介します。
1 「そんなに悪くはない
これは、このような苦情に対する非常に一般的な反応です。あなたのコードに数行の余分なコードがあるという事実は、実際にはそれほど悪いことではありません。それはちょっとした安っぽいタイピングであり、読む側としては非常に扱いやすいものです。
2 - それは実際には良いことです
これは、これらの余分な行を入力し、読むことは、実際にあなたのロジックがその時点で逃げるかもしれないことを非常によく思い出させるという事実に基づいていますし、その前の行で配置したすべてのリソース管理を元に戻す必要があります。これは通常、例外との比較で取り上げられますが、例外は暗黙のうちにロジックの流れを壊してしまうので、開発者は常に隠れたエラーの経路を念頭に置くことを余儀なくされます。少し前に、私はこのことについてより深い戯言を書きました。 ここで .
3 - パニック/リカバリーを使う
特定の状況においては
panic
を既知の型とし、次に
recover
を使い、パッケージコードが世に出る直前にそれを適切なエラーに変換し、代わりにそれを返します。この手法は、(un) marshalers などの再帰的なロジックを展開するために最も一般的に使用されます。
私は個人的に、ポイント 1 と 2 により密接に関連するため、これをあまり乱用しないように努めています。
4 - コードを少し再編成する
状況によっては、繰り返しを避けるために、ロジックを少し再編成することができます。
些細な例として、これ。
err := doA()
if err != nil {
return err
}
err := doB()
if err != nil {
return err
}
return nil
のように整理することもできる。
err := doA()
if err != nil {
return err
}
return doB()
5 - 名前付きの結果を使用する
returnステートメントからerr変数を取り除くために、名前付き結果を使用する人がいます。なぜなら、ほとんど節約にならず、コードの明快さが失われ、1つ以上の結果が救済のためのreturn文の前に定義されると、ロジックが微妙な問題に陥りやすくなるからです。
6 - if条件の前にステートメントを使用する
Tom Wildeが下のコメントでよく言っていた通りです。
if
文は
は単純なステートメントを受け入れる
を条件の前に置くことができます。だから、こんなことができる。
if err := doA(); err != nil {
return err
}
これは立派なGoイディオムで、よく使われます。
いくつかの具体的なケースでは、わかりやすくするために、この方法でステートメントを埋め込むことだけは避けたいのですが、これは微妙に個人的なことです。
関連
-
[解決済み] ランタイムエラー:nilマップのエントリへの代入
-
[解決済み] Go: パニック: ランタイム エラー: 無効なメモリ アドレスまたは nil ポインタのデリファレンス
-
[解決済み] 2枚のスライスの等価性を確認する
-
[解決済み] "宣言されているが使用されていない "という迷惑なエラーを回避する方法
-
[解決済み] Goのnil検出
-
[解決済み] ログをファイルに書き出す方法
-
[解決済み] ...interface{}の意味 (ドット・ドット・ドット・インターフェース)
-
[解決済み] Go で POST リクエストを送信するには?
-
[解決済み] Go テンプレートで変数キーを使用してマップ値にアクセスする
-
[解決済み] Golang で os/exec で開始したプロセスを終了させる
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] ゴルーチンの停止方法
-
[解決済み] Goでスライスを逆に反復処理する方法はありますか?
-
[解決済み] 構造体の値をマップの値として設定すると、"cannot assign" エラーが発生するのはなぜですか?重複
-
[解決済み] Goエラー処理テクニック【終了しました
-
[解決済み] Goにはラムダ式というものがあるのですか?
-
[解決済み] Go で要件をインストールするにはどうすればよいですか? "パッケージが見つかりません"
-
[解決済み] スライスは値で渡されるのか?
-
[解決済み] Goで実行時に構造体の型から新しいインスタンスを作成するにはどうすればよいですか?
-
[解決済み] go.sum ファイルは git リポジトリにチェックインする必要がありますか?
-
[解決済み] golangでエラーメッセージを文字列で取得するには?