Goでは、JavaScriptなどの他の言語のようなtry-catchメカニズムはありません。
try {
// エラー発生
} catch(error) {
// エラー処理
}
その代わりに、Goはエラーを表現するためのerrorインターフェース型を提供します。エラーインターフェースにはError()メソッドがあり、エラーメッセージを文字列で返します。
type error interface {
Error() string
}
Goのエラーはこのerror型のインターフェースを使い、値で表現することになっています。 Goにおけるエラー値は下のようにまとめられます。
Goでは、errorがnilかどうかを調べることで、エラーを処理することができます。それでは、ファイルの中身を読み込む次のような関数を考えてみましょう。
// ファイルを読み取りその内容を返すと共にerror型の値も返します
func ReadFile() ([]byte, error) {
// os.Open関数を用いてファイルをオープンし、ファイルディスクリプタとエラー値を返します
// ファイルが正常にオープンされた場合、エラー値はnilとなります。エラーが発生した場合、エラー値はnilでない値になります
f, err := os.Open("test.txt")
// もしerrがnilではない値の場合はファイルの開封に失敗しているので、この関数の実行結果はエラーということになり、発生したエラーを値として返します
if err != nil {
return nil, err
}
defer f.Close()
// 同様に、ファイルの内容を読み取る処理も行います
data, err := io.ReadAll(f)
if err != nil {
return nil, err
}
// ファイルオープンとファイル内容の読み取りに成功した場合はエラーなしと判断し、この関数のエラーをnilとして返します
// このようにすることで、この関数の二つ目の返り値であるerrorの値を見ることで、実行結果がエラーなのかエラーでないのかを関数外から判定することができます
return data, nil
}
関数からエラー値を返すことで、関数の呼び出し側に、エラーが発生したことと、そのエラーメッセージを知らせることができます。
Goでは、関数から返されたエラー値を確認し、そのエラー値に基づいて適切な対処を行うことでエラー処理を行います。try-catch構文に慣れている人には違和感があるかもしれませんが、エラーを単なる値として考えることで、Goでのエラー処理をより自然に感じられるようになります。
Goでカスタムエラーを作成するには、errorインターフェースのError()メソッドを実装した新しい型を定義するだけです。このメソッドは、エラーを説明する文字列を返す必要があります。
たとえば、ネットワーク接続に失敗した場合のエラータイプを作りたいとします。このような新しい型を定義することができます。
type NetworkError struct {
message string
}
func (err *NetworkError) Error() string {
return fmt.Sprintf("Network Error: %s", err.message)
}
この例では、messageというフィールドを1つ持つNetworkErrorという新しい型を定義しています。また、Error()というメソッドを定義し、エラーメッセージの文字列を"Network Error:"というプレフィックス付きで返します。この新しい型を使用して、独自のエラーを作成したり返したりすることができます。
package main
import "fmt"
type NetworkError struct {
message string
}
func (err *NetworkError) Error() string {
return fmt.Sprintf("Network Error: %s", err.message)
}
func connect() error {
return &NetworkError{"Could not connect to server"}
}
func main() {
err := connect()
if err != nil {
fmt.Println(err.Error())
}
}
この例では、NetworkError型のカスタムエラーを返すconnect関数を作成しました。次にmain関数の中でこの関数を呼び出し、エラーが発生しているかどうかをチェックします。エラーが返された場合は、Error()メソッドを使用してエラーメッセージを出力します。
カスタムエラーは具体的なエラーメッセージをユーザーや開発者に提供するのに便利です。また、エラーの種類を区別して、より具体的な方法でエラーを処理しやすくするためにも使用することができます。