Menu
Coddy logo textTech

A Interface error

Parte da seção Programação Orientada a Objetos do Journey de GO da Coddy — lição 52 de 107.

Em Go, os erros são tratados por meio de uma interface integrada chamada error. Esta interface é notavelmente simples — ela requer apenas um método:

type error interface {
    Error() string
}

Qualquer tipo que implemente um método Error() que retorna uma string satisfaz automaticamente a interface error. Este é o sistema de interfaces do Go em funcionamento — nenhuma declaração explícita é necessária.

A maneira mais comum de criar erros é usando o pacote 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
}

As funções em Go normalmente retornam um erro como seu último valor de retorno. Quando nenhum erro ocorre, você retorna nil. O chamador então verifica se o erro não é nulo antes de prosseguir:

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

Você também pode usar fmt.Errorf para criar mensagens de erro formatadas:

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

Este padrão de retornar erros em vez de lançar exceções é fundamental para o Go. Isso torna o tratamento de erros explícito e força você a considerar o que acontece quando as coisas dão errado — um aspecto fundamental para escrever código robusto e orientado a objetos.

challenge icon

Desafio

Fácil

Vamos construir um sistema de conta bancária que demonstra o padrão de tratamento de erros do Go. Você criará uma conta simples que valida operações e retorna erros significativos quando algo dá errado.

Você organizará seu código em dois arquivos:

  • account.go: Crie uma struct BankAccount com um campo exportado Owner (string) e um campo não exportado balance (float64). Implemente o seguinte:
    • NewBankAccount(owner string, initialDeposit float64) (*BankAccount, error) - um construtor que retorna um erro com a mensagem "initial deposit must be positive" se o depósito inicial for zero ou negativo. Caso contrário, crie e retorne a conta.
    • Deposit(amount float64) error - adiciona dinheiro ao saldo. Retorne um erro com a mensagem "deposit amount must be positive" se o valor for zero ou negativo.
    • Withdraw(amount float64) error - remove dinheiro do saldo. Retorne um erro com a mensagem "withdrawal amount must be positive" se o valor for zero ou negativo, ou "insufficient funds" se o saldo for menor que o valor do saque.
    • Balance() float64 - retorna o saldo atual
  • main.go: Leia os detalhes da conta e os valores das transações da entrada. Tente criar uma conta e realizar as operações. Após cada operação, imprima a mensagem de sucesso ou a mensagem de erro.

As seguintes entradas serão fornecidas:

  • Linha 1: Nome do proprietário (Owner)
  • Linha 2: Valor do depósito inicial
  • Linha 3: Valor do depósito
  • Linha 4: Valor do saque

Para cada operação, imprima o resultado:

  • Após a criação da conta: Account created for [Owner] with balance: $[balance] ou Error: [error message]
  • Após o depósito: Deposited successfully. New balance: $[balance] ou Error: [error message]
  • Após o saque: Withdrew successfully. New balance: $[balance] ou Error: [error message]

Formate todos os valores de saldo com duas casas decimais. Se a criação da conta falhar, pule as operações restantes.

Por exemplo, dados Alice, 100, 50, e 200, sua saída deve ser:

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

E dados Bob, -50, 25, e 10, sua saída deve ser:

Error: initial deposit must be positive

Folha de consulta

O Go lida com erros por meio da interface error integrada, que requer um único método:

type error interface {
    Error() string
}

Crie erros usando o pacote 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
}

As funções retornam erros como o último valor de retorno. Retorne nil quando nenhum erro ocorrer:

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

Use fmt.Errorf para mensagens de erro formatadas:

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

Experimente você mesmo

package main

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

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

	// Ler o nome do proprietário
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)

	// Ler o depósito inicial
	initialDepositStr, _ := reader.ReadString('\n')
	initialDeposit, _ := strconv.ParseFloat(strings.TrimSpace(initialDepositStr), 64)

	// Ler o valor do depósito
	depositStr, _ := reader.ReadString('\n')
	depositAmount, _ := strconv.ParseFloat(strings.TrimSpace(depositStr), 64)

	// Ler o valor do saque
	withdrawStr, _ := reader.ReadString('\n')
	withdrawAmount, _ := strconv.ParseFloat(strings.TrimSpace(withdrawStr), 64)

	// TODO: Criar uma nova conta bancária usando NewBankAccount
	// Se houver um erro, imprima "Error: [error message]" e retorne
	// Se for bem-sucedido, imprima "Account created for [Owner] with balance: $[balance]"

	// TODO: Tentar depositar o valor do depósito
	// Se houver um erro, imprima "Error: [error message]"
	// Se for bem-sucedido, imprima "Deposited successfully. New balance: $[balance]"

	// TODO: Tentar sacar o valor do saque
	// Se houver um erro, imprima "Error: [error message]"
	// Se for bem-sucedido, imprima "Withdrew successfully. New balance: $[balance]"

	// Lembre-se de formatar os valores de saldo com duas casas decimais usando fmt.Printf("%.2f", balance)

	_ = ownerName
	_ = initialDeposit
	_ = depositAmount
	_ = withdrawAmount
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos