Menu
Coddy logo textTech

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 の基本です。エラー処理を明示的にし、問題が発生したときに何が起こるかを考えるよう促します。これは、堅牢なオブジェクト指向コードを書くうえで重要な要素です。

challenge icon

チャレンジ

簡単

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 桁で表示してください。口座の作成に失敗した場合は、残りの操作をスキップします。

たとえば、Alice10050200 が与えられた場合、出力は次のようになります。

Account created for Alice with balance: $100.00
Deposited successfully. New balance: $150.00
Error: insufficient funds

また、Bob-502510 が与えられた場合、出力は次のようになります。

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
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Goオンラインコンパイラ