(X, error)
正常に実行または中止を返す関数を作成するための、より組み込みのラッパーはありますregexp.MustCompile
か?
私はこのようなことについて話しているが、もっと「ビルトイン」である。
存在しない。あなたが得る最高のものはこのようなものです:
func Must(fn func() (interface{}, error)) interface{} {
v, err := fn()
if err != nil {
log.Fatalln(err)
}
return v
}
次にそれを使用するには:
Must(func() (interface{}, error) {
return template.ParseGlob(pattern)
}).(*template.Template)
template.ParseGlob(pattern)
それがあなたがラップしたかった呼び出しであると仮定します。
Goにはパラメトリック多相性がないため、この種のコードでは、元の型を復元するために型アサーションが必要になるため、(私の意見では)その価値よりも多くの労力が必要になります。潜在的な障害の長いチェーンに対して得られる最も整然とした慣用的なエラー処理は、単にエラーをチェックして返すことです。クリーンアップハンドラーを延期します。
func MyFunc() (err error) {
a, err := blah1()
if err != nil {
return
}
defer a.Close()
b, err := blah2(a)
if err != nil {
return
}
defer b.Close()
// ad nauseam
}
長くて退屈ですが、少なくともそれは明確でわかりやすいです。これが私が書いた2つのモジュールで、パラメトリック多態性を求めており、それなしで対処するためのアイデアを提供する可能性があります。
テンプレートパッケージ自体の例のように、さまざまな方法でnil以外のエラーを非常にうまく処理できるため、組み込みのメカニズムは意味をなさないと思います。「text/template/examplefiles_test.go
」を参照してくださいerr
。
// Here starts the example proper.
// T0.tmpl is the first name matched, so it becomes the starting template,
// the value returned by ParseGlob.
tmpl := template.Must(template.ParseGlob(pattern))
err := tmpl.Execute(os.Stdout, nil)
if err != nil {
log.Fatalf("template execution: %s", err)
}
// Output:
// T0 invokes T1: (T1 invokes T2: (This is T2))
ヘルパー関数の特定のケースでは(*Template) Must()
、エラーを例外(パニック)に変換することは、すべてのgoプログラム(このスレッドで議論されているように)にとって常に正しいコースであるとは限りません。エラーを処理するためのすべての可能な方法をカバーすることは、多くの「組み込み」メカニズムを作成します。
私自身も同じ問題に遭遇し、次のソリューションを開発することにしました:https ://github.com/boramalper/must
例:
database := must.MV(sql.Open("sqlite3", "...")).(*sql.DB)
defer must.M(database.Close())
must.M(database.Ping())
// Use MustValVoid (or MVV shortly) if you don't care about
// the return value.
must.MVV(database.Exec(`
PRAGMA foreign_key_check;
...
`))
ソース自体が使用しているのに、なぜここですべての答えがlog
パッケージを使用しているのかわかりませんpanic
:
func MustCompile(str string) *Regexp {
regexp, err := Compile(str)
if err != nil {
panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
}
return regexp
}
私の推奨は、汎用Must
ラッパー
の代わりに、Must
必要に応じてコードにバリアントを実装することです。