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 eine Zeichenkette zurückgibt, erfüllt automatisch das error-Interface. Das ist Go's Interfacesystem in Aktion: Keine explizite Deklaration erforderlich.

Die häufigste Methode zum Erstellen von Fehlern ist die Verwendung des Pakets 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-Funktionen geben typischerweise einen Fehler als ihren letzten Rückgabewert zurück. Wenn kein Fehler auftritt, gibst du nil zurück. Der Aufrufer prüft dann, ob der Fehler nicht nil ist, bevor er fortfährt:

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

Du kannst 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 Ausnahmen auszulösen, ist grundlegend für Go. Es macht die Fehlerbehandlung explizit und zwingt dich dazu, zu berücksichtigen, was passiert, wenn etwas schiefgeht: ein wesentlicher Aspekt beim Schreiben robusten objektorientierten Codes.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Bankkontosystem, das Gos Muster zur Fehlerbehandlung demonstriert. Du erstellst ein einfaches Konto, das Operationen validiert und aussagekräftige Fehler zurückgibt, wenn etwas schiefgeht.

Du organisierst deinen Code über zwei Dateien:

  • account.go: Erstelle eine BankAccount-Struktur mit einem exportierten Feld Owner (string) und einem nicht exportierten Feld balance (float64). Implementiere Folgendes:
    • NewBankAccount(owner string, initialDeposit float64) (*BankAccount, error) – einen Konstruktor, der einen Fehler mit der Meldung "initial deposit must be positive" zurückgibt, wenn die Ersteinzahlung null oder negativ ist. Erstelle und gib andernfalls das Konto zurück.
    • Deposit(amount float64) error – fügt dem Kontostand Geld hinzu. Gibt einen Fehler mit der Meldung "deposit amount must be positive" zurück, wenn der Betrag null oder negativ ist.
    • Withdraw(amount float64) error – entfernt Geld vom Kontostand. Gibt einen Fehler mit der Meldung "withdrawal amount must be positive" zurück, wenn der Betrag null oder negativ ist, oder "insufficient funds", wenn der Kontostand geringer als der Abhebungsbetrag ist.
    • Balance() float64 – gibt den aktuellen Kontostand zurück
  • main.go: Lies Kontodetails und Transaktionsbeträge aus der Eingabe ein. Versuche, ein Konto zu erstellen und Operationen auszuführen. Gib nach jeder Operation entweder die Erfolgsmeldung oder die Fehlermeldung aus.

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Name des Kontoinhabers
  • Zeile 2: Betrag der Ersteinzahlung
  • Zeile 3: Einzahlungsbetrag
  • Zeile 4: Abhebungsbetrag

Gib 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]

Formatiere alle Kontostandwerte mit zwei Dezimalstellen. Wenn die Kontoerstellung fehlschlägt, überspringe die verbleibenden Operationen.

Wenn beispielsweise Alice, 100, 50 und 200 angegeben werden, sollte deine Ausgabe wie folgt aussehen:

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

Und wenn Bob, -50, 25 und 10 angegeben werden, sollte deine Ausgabe wie folgt aussehen:

Error: initial deposit must be positive

Probier es selbst

package main

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

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

	// Namen des Inhabers lesen
	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: Erstelle ein neues Bankkonto mit NewBankAccount
	// Wenn ein Fehler auftritt, drucke "Error: [error message]" und kehre zurück
	// Bei Erfolg drucke "Account created for [Owner] with balance: $[balance]"

	// TODO: Versuche, den Einzahlungsbetrag einzuzahlen
	// Wenn ein Fehler auftritt, drucke "Error: [error message]"
	// If successful, print "Deposited successfully. New balance: $[balance]"

	// TODO: Versuche, den Abhebungsbetrag abzuheben
	// Wenn ein Fehler auftritt, drucke "Error: [error message]"
	// If successful, print "Withdrew successfully. New balance: $[balance]"

	// Denke daran, Kontostandswerte mit zwei Dezimalstellen mit 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

Übe selbstständig: Online-Go-Compiler