はじめに
エラーハンドリングは、コードの安定性・堅牢性には必要不可欠です。
今回は、 前回作成した greetings モジュール に少しだけコードを追加しながら、以下の内容について学んで行きます。
- モジュールからエラーを返却する方法
- モジュールから返却されたエラーを呼び出し元でハンドリングする方法
当エントリは以下のエントリの続きとなっています。事前に一読しておくことをおすすめします。
コーディング開始
早速コーディングを始めていきます。
1. greetings/greetings.go を開き、コードを追記
「挨拶をする相手の名前がわからない場合には、挨拶をせずにエラーとする」、 そんな仕様を追加してみます。
name パラメータが空だった場合には、呼び出し元にエラーを返却します。 以下のコードを greetings.go に記述します。
| |
もともとのコード から変更した箇所は以下のようになります。( git diff 実行結果を添付 )
| |
コード解説
かんたんに解説します。
- 関数は 2 つの値を返却するように変更されています。
- 1 つは string 型の値、 1 つは error 型の値。
- 呼び出し元では 2 つ目に返却された値をチェックすることで、エラーが発生したかがわかります ( Go の関数は複数の値を返却することができるんですね ) 。
- Go の
errorsという標準ライブラリをインポートし、errors.New関数 ( 後述 ) を利用できるようにします。 if構文を使って、nameパラメータが妥当か(空ではないか?)をチェックしています。- 空の場合
- エラーを返却します。
- エラーを返却する場合は、 error 型の値を生成するために
errors.New関数を利用します。任意のメッセージを格納することができます。
- 空でない場合
- エラーを返却しません。
- エラーを返却しない場合は、 2 つ目の戻り値に
nilを設定します。
- 空の場合
Hello 関数の呼び出し元は 2 つ目の戻り値を確認し、 nil であれば正常終了したと判断できます。
2. hello/hello.go を開き、 Hello 関数からの戻り値をハンドリングするコードを追加
以下のコードを貼り付けます。
| |
もともとのコード から変更した箇所は以下のようになります。( git diff 実行結果を添付 )
| |
コード解説
かんたんに解説します。
logパッケージを import しています。- すべてのログのプレフィックスとして
greetings:という文字列を出力する。 - すべてのログのプレフィックスとして タイムスタンプ や ソースコード名 を出力しない。 (
log.SetFlags(0))
- すべてのログのプレフィックスとして
Hello関数の戻り値 2 つを受け取ります。Hello関数の引数を変更し、genzouwという名前 から 空文字 をセットするようにしています。err変数が nil ではない場合、処理を中断します。- 標準ライブラリ
logのFatal関数を呼び出すことで、エラーメッセージを出力しています。log.Fatal実行後はプログラムがエラーステータスで終了します。
アプリケーション実行
hello モジュールの配置されているディレクトリで、コードを実行してみます。
| |
想定通り、異常終了してくれました。
greetings.Hello("") の部分を greetings.Hello("genzouw") のように空文字列ではないものに変更すれば、正常に動作します。
| |
まとめ
Go 言語では、関数の呼び出し元にエラーを通知する方法として、C++/Java/C#といった他の言語のように 「例外を投げる方法」 ではなく、 「戻り値として返却する方法」 を取ります。
ひとこと
次回は **「挨拶」プログラムの実行結果を実行のたびにランダムに変更 ** してみます。