Menu
Coddy logo textTech

Das error-Interface

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy — Lektion 52 von 107.

In Go werden Fehler über ein integriertes Interface namens error behandelt. Dieses Interface ist bemerkenswert einfach – es erfordert nur eine Methode:

type error interface {
    Error() string
}

Jeder Typ, der eine Error()-Methode implementiert, die einen String zurückgibt, erfüllt automatisch das error-Interface. Dies ist das Interface-System von Go in Aktion – es ist keine explizite Deklaration erforderlich.

Die gängigste Art, Fehler zu erstellen, ist die Verwendung des errors-Packages:

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-Funktionen geben normalerweise einen Fehler als ihren letzten Rückgabewert zurück. Wenn kein Fehler auftritt, geben Sie nil zurück. Der Aufrufer prüft dann, ob der Fehler ungleich nil ist, bevor er fortfährt:

result, err := Divide(10, 0)
if err != nil {
    fmt.Println("Error:", err.Error())
    return
}
fmt.Println("Result:", result)

Sie können auch fmt.Errorf verwenden, um formatierte Fehlermeldungen zu erstellen:

func GetUser(id int) (string, error) {
    if id <= 0 {
        return "", fmt.Errorf("invalid user id: %d", id)
    }
    return "Alice", nil
}

Dieses Muster, Fehler zurückzugeben, anstatt Exceptions zu werfen, ist grundlegend für Go. Es macht die Fehlerbehandlung explizit und zwingt dazu, zu bedenken, was passiert, wenn etwas schiefgeht – ein zentraler Aspekt beim Schreiben von robustem, objektorientiertem Code.

challenge icon

Aufgabe

Einfach

Lassen Sie uns ein Bankkontosystem erstellen, das das Fehlerbehandlungsmuster von Go demonstriert. Sie werden ein einfaches Konto erstellen, das Operationen validiert und aussagekräftige Fehler zurückgibt, wenn etwas schiefgeht.

Sie werden Ihren Code auf zwei Dateien aufteilen:

  • account.go: Erstellen Sie eine BankAccount-Struktur mit einem exportierten Owner-Feld (string) und einem nicht exportierten balance-Feld (float64). Implementieren Sie Folgendes:
    • NewBankAccount(owner string, initialDeposit float64) (*BankAccount, error) - ein Konstruktor, der einen Fehler mit der Nachricht "initial deposit must be positive" zurückgibt, wenn die Ersteinzahlung null oder negativ ist. Andernfalls erstellen und geben Sie das Konto zurück.
    • Deposit(amount float64) error - fügt dem Guthaben Geld hinzu. Geben Sie einen Fehler mit der Nachricht "deposit amount must be positive" zurück, wenn der Betrag null oder negativ ist.
    • Withdraw(amount float64) error - hebt Geld vom Guthaben ab. Geben Sie einen Fehler mit der Nachricht "withdrawal amount must be positive" zurück, wenn der Betrag null oder negativ ist, oder "insufficient funds", wenn das Guthaben geringer als der Abhebungsbetrag ist.
    • Balance() float64 - gibt das aktuelle Guthaben zurück
  • main.go: Lesen Sie Kontodetails und Transaktionsbeträge aus der Eingabe. Versuchen Sie, ein Konto zu erstellen und Operationen durchzuführen. Geben Sie nach jeder Operation entweder die Erfolgsmeldung oder die Fehlermeldung aus.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Name des Eigentümers
  • Zeile 2: Ersteinzahlungsbetrag
  • Zeile 3: Einzahlungsbetrag
  • Zeile 4: Abhebungsbetrag

Geben Sie für jede Operation das Ergebnis aus:

  • Nach der Kontoerstellung: Account created for [Owner] with balance: $[balance] oder Error: [error message]
  • Nach der Einzahlung: Deposited successfully. New balance: $[balance] oder Error: [error message]
  • Nach der Abhebung: Withdrew successfully. New balance: $[balance] oder Error: [error message]

Formatieren Sie alle Guthabenwerte mit zwei Dezimalstellen. Wenn die Kontoerstellung fehlschlägt, überspringen Sie die verbleibenden Operationen.

Zum Beispiel, bei Alice, 100, 50 und 200 sollte Ihre Ausgabe wie folgt aussehen:

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

Und bei Bob, -50, 25 und 10 sollte Ihre Ausgabe wie folgt aussehen:

Error: initial deposit must be positive

Spickzettel

Go verarbeitet Fehler über das integrierte error-Interface, das eine einzige Methode erfordert:

type error interface {
    Error() string
}

Erstellen Sie Fehler mit dem errors-Paket:

import "errors"

func Divide(a, b int) (int, error) {
    if b == 0 {
        return 0, errors.New("cannot divide by zero")
    }
    return a / b, nil
}

Funktionen geben Fehler als letzten Rückgabewert zurück. Geben Sie nil zurück, wenn kein Fehler auftritt:

result, err := Divide(10, 0)
if err != nil {
    fmt.Println("Error:", err.Error())
    return
}
fmt.Println("Result:", result)

Verwenden Sie fmt.Errorf für formatierte Fehlermeldungen:

func GetUser(id int) (string, error) {
    if id <= 0 {
        return "", fmt.Errorf("invalid user id: %d", id)
    }
    return "Alice", nil
}

Probier es selbst

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Inhabername lesen
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)

	// Anfangseinzahlung lesen
	initialDepositStr, _ := reader.ReadString('\n')
	initialDeposit, _ := strconv.ParseFloat(strings.TrimSpace(initialDepositStr), 64)

	// Einzahlungsbetrag lesen
	depositStr, _ := reader.ReadString('\n')
	depositAmount, _ := strconv.ParseFloat(strings.TrimSpace(depositStr), 64)

	// Auszahlungsbetrag lesen
	withdrawStr, _ := reader.ReadString('\n')
	withdrawAmount, _ := strconv.ParseFloat(strings.TrimSpace(withdrawStr), 64)

	// TODO: Erstelle ein neues Bankkonto mit NewBankAccount
	// Wenn ein Fehler auftritt, gib "Error: [error message]" aus und beende die Funktion
	// Wenn erfolgreich, gib "Account created for [Owner] with balance: $[balance]" aus

	// TODO: Versuche, den Einzahlungsbetrag einzuzahlen
	// Wenn ein Fehler auftritt, gib "Error: [error message]" aus
	// Wenn erfolgreich, gib "Deposited successfully. New balance: $[balance]" aus

	// TODO: Versuche, den Auszahlungsbetrag abzuheben
	// Wenn ein Fehler auftritt, gib "Error: [error message]" aus
	// Wenn erfolgreich, gib "Withdrew successfully. New balance: $[balance]" aus

	// Denke daran, die Kontostandswerte mit zwei Dezimalstellen unter Verwendung von fmt.Printf("%.2f", balance) zu formatieren

	_ = ownerName
	_ = initialDeposit
	_ = depositAmount
	_ = withdrawAmount
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung