error インターフェース
CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 52/107。
Go では、エラーは組み込みの interface である error を通じて処理されます。この interface は非常にシンプルです。必要なのは次の 1 つのメソッドだけです。
type error interface {
Error() string
}文字列を返す Error() メソッドを実装する任意の型は、自動的に error インターフェースを満たします。これはGoのインターフェースシステムが機能している例です。明示的な宣言は必要ありません。
エラーを作成する最も一般的な方法は、errors パッケージを使用することです。
import "errors"
func Divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}Goの関数は通常、最後の戻り値としてエラーを返します。エラーが発生しない場合は、nilを返します。呼び出し側はその後、処理を続行する前にエラーが非nilかどうかを確認します:
result, err := Divide(10, 0)
if err != nil {
fmt.Println("Error:", err.Error())
return
}
fmt.Println("Result:", result)整形されたエラーメッセージを作成するには、fmt.Errorfも使用できます。
func GetUser(id int) (string, error) {
if id <= 0 {
return "", fmt.Errorf("invalid user id: %d", id)
}
return "Alice", nil
}例外をスローするのではなくエラーを返すこのパターンは、Go の基本です。エラー処理を明示的にし、問題が発生したときに何が起こるかを考えるよう促します。これは、堅牢なオブジェクト指向コードを書くうえで重要な要素です。
チャレンジ
簡単Go のエラーハンドリングパターンを示す銀行口座システムを構築しましょう。操作を検証し、問題が発生した場合に意味のあるエラーを返すシンプルな口座を作成します。
コードを 2 つのファイルに分けて構成します。
account.go: エクスポートされたOwnerフィールド(string)と、エクスポートされていないbalanceフィールド(float64)を持つBankAccount構造体を作成します。以下を実装してください。NewBankAccount(owner string, initialDeposit float64) (*BankAccount, error)- 初期預金がゼロまたは負の場合、メッセージ"initial deposit must be positive"のエラーを返すコンストラクター。それ以外の場合は、口座を作成して返します。Deposit(amount float64) error- 残高に入金します。金額がゼロまたは負の場合は、メッセージ"deposit amount must be positive"のエラーを返します。Withdraw(amount float64) error- 残高から出金します。金額がゼロまたは負の場合はメッセージ"withdrawal amount must be positive"のエラーを返し、残高が出金額より少ない場合は"insufficient funds"のエラーを返します。Balance() float64- 現在の残高を返します
main.go: 入力から口座の詳細と取引金額を読み取ります。口座の作成と操作を試みます。各操作の後に、成功メッセージまたはエラーメッセージを出力します。
次の入力が提供されます。
- 1 行目: 所有者名
- 2 行目: 初期預金額
- 3 行目: 入金額
- 4 行目: 出金額
各操作の結果を出力します。
- 口座作成後:
Account created for [Owner] with balance: $[balance]またはError: [error message] - 入金後:
Deposited successfully. New balance: $[balance]またはError: [error message] - 出金後:
Withdrew successfully. New balance: $[balance]またはError: [error message]
すべての残高の値は小数点以下 2 桁で表示してください。口座の作成に失敗した場合は、残りの操作をスキップします。
たとえば、Alice、100、50、200 が与えられた場合、出力は次のようになります。
Account created for Alice with balance: $100.00
Deposited successfully. New balance: $150.00
Error: insufficient fundsまた、Bob、-50、25、10 が与えられた場合、出力は次のようになります。
Error: initial deposit must be positive自分で試してみよう
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// 所有者名を読み取る
ownerName, _ := reader.ReadString('\n')
ownerName = strings.TrimSpace(ownerName)
// Read initial deposit
initialDepositStr, _ := reader.ReadString('\n')
initialDeposit, _ := strconv.ParseFloat(strings.TrimSpace(initialDepositStr), 64)
// Read deposit amount
depositStr, _ := reader.ReadString('\n')
depositAmount, _ := strconv.ParseFloat(strings.TrimSpace(depositStr), 64)
// Read withdrawal amount
withdrawStr, _ := reader.ReadString('\n')
withdrawAmount, _ := strconv.ParseFloat(strings.TrimSpace(withdrawStr), 64)
// TODO: NewBankAccountを使用して新しい銀行口座を作成する
// エラーがある場合は、"Error: [error message]"を出力してreturnする
// 成功した場合は、"Account created for [Owner] with balance: $[balance]"を出力する
// TODO: 入金額の預け入れを試みる
// エラーがある場合は、"Error: [error message]"を出力する
// If successful, print "Deposited successfully. New balance: $[balance]"
// TODO: 出金額の引き出しを試みる
// エラーがある場合は、"Error: [error message]"を出力する
// If successful, print "Withdrew successfully. New balance: $[balance]"
// 残高の値はfmt.Printf("%.2f", balance)を使用して小数点以下2桁でフォーマットすることを忘れないでください
_ = ownerName
_ = initialDeposit
_ = depositAmount
_ = withdrawAmount
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー自分で練習してみよう: Goオンラインコンパイラ