Go の Must のついたメソッド

今日は Go について書きます。今回はさらっと。

github.com/jmoiron/sqlx を使っていて MustExec と Exec の違いなんだっけ、となったのでどんなメソッドに Must が付くか調べ直しました。

結論

先に結論です。

Must のついたメソッド: エラーが発生した場合に panic を発生させる関数

Must のないメソッド: エラーが発生した場合、返り値で error を返す関数

よって、絶対にエラーが発生しない(正規表現コンパイルとか、html の template とかコンパイル時には既に確定している内容)処理の場合のみ Must のついたメソッドを使用してよいです。

実行時に panic を起こす可能性がある場合は Must のないメソッドを使用し、エラー処理をしっかり行う必要があります。

sqlx の例

まずは冒頭で触れた sqlx の godoc を見てみます。

func (*NamedStmt) Exec

func (n *NamedStmt) Exec(arg interface{}) (sql.Result, error)

Exec executes a named statement using the struct passed. Any named placeholder parameters are replaced with fields from arg.

func (*NamedStmt) MustExec

func (n *NamedStmt) MustExec(arg interface{}) sql.Result

MustExec execs a NamedStmt, panicing on error Any named placeholder parameters are replaced with fields from arg.

Exec は 返り値として sql.Result と error を返します。 MustExec は返り値として sql.Result のみを返し、

panicing on error

します。 その他は基本同じですね。

プログラミング言語 Go での記述

プログラミング言語 Go を読んだときに何回か出てきたなーという印象だったため、読み返して見ました。

4.6 節で html/template パッケージの例を出している場所で以下のように述べられています。

テンプレートはたいていコンパイル時に確定しているので、テンプレートのパースに失敗するというのはプログラムの致命的なバグを示しています。template.Must ヘルパー関数はエラー処理をより便利にしています。その関数はテンプレートとエラーを受け付けて、エラーが nil であるかを検査し(nil でなければパニックになります)、そしてそのテンプレートを返ます。

事前に用意した正しいテンプレートを用いる場合、パースに失敗するはずがない(あれば致命的なバグ)であるということですね。 逆に、(あまりないでしょうが)プログラム中で動的にテンプレートを生成する場合は、パースに失敗しうるのでエラーチェックを正しく実装すべきです。

regexp

Must が出てくる他の例は標準パッケージの regexp です。

正規表現も固定の文字列を用いる場合がほとんどで、コンパイル時には確定しているというわけですね。

godoc には以下のようにあります。

func MustCompile

func MustCompile(str string) *Regexp

MustCompile is like Compile but panics if the expression cannot be parsed. It simplifies safe initialization of global variables holding compiled regular expressions.

終わりに

他の言語ではあまり見ないような気がするので、Go 特有の命名でしょうか。 適切に使い分けていきたいと思います。