Menu
Coddy logo textTech

error 인터페이스

Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 52번째.

Go에서 에러는 error라는 내장 인터페이스를 통해 처리됩니다. 이 인터페이스는 매우 간단하며, 단 하나의 메서드만 필요합니다:

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의 에러 처리 패턴을 보여주는 은행 계좌 시스템을 구축해 보겠습니다. 작업 내용을 검증하고 문제가 발생했을 때 의미 있는 에러를 반환하는 간단한 계좌를 만들 것입니다.

코드는 두 개의 파일로 구성됩니다:

  • account.go: 외부로 노출되는 Owner 필드(string)와 노출되지 않는 balance 필드(float64)를 가진 BankAccount 구조체를 생성합니다. 다음을 구현하세요:
    • NewBankAccount(owner string, initialDeposit float64) (*BankAccount, error) - 초기 예치금이 0 이하인 경우 "initial deposit must be positive"라는 메시지와 함께 에러를 반환하는 생성자입니다. 그렇지 않으면 계좌를 생성하여 반환합니다.
    • Deposit(amount float64) error - 잔액에 돈을 추가합니다. 금액이 0 이하인 경우 "deposit amount must be positive" 메시지와 함께 에러를 반환합니다.
    • Withdraw(amount float64) error - 잔액에서 돈을 인출합니다. 금액이 0 이하인 경우 "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]

모든 잔액 값은 소수점 둘째 자리까지 형식화하세요. 계좌 생성이 실패하면 나머지 작업은 건너뜁니다.

예를 들어, 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

치트 시트

Go는 내장된 error 인터페이스를 통해 에러를 처리하며, 이 인터페이스는 단일 메서드를 요구합니다:

type error interface {
    Error() string
}

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
}

함수는 에러를 마지막 반환 값으로 반환합니다. 에러가 발생하지 않으면 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
}

직접 해보기

package main

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

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

	// 소유자 이름 읽기
	ownerName, _ := reader.ReadString('\n')
	ownerName = strings.TrimSpace(ownerName)

	// 초기 예금액 읽기
	initialDepositStr, _ := reader.ReadString('\n')
	initialDeposit, _ := strconv.ParseFloat(strings.TrimSpace(initialDepositStr), 64)

	// 입금액 읽기
	depositStr, _ := reader.ReadString('\n')
	depositAmount, _ := strconv.ParseFloat(strings.TrimSpace(depositStr), 64)

	// 출금액 읽기
	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]"를 출력
	// 성공하면 "Deposited successfully. New balance: $[balance]"를 출력

	// TODO: 출금액 출금 시도
	// 에러가 발생하면 "Error: [error message]"를 출력
	// 성공하면 "Withdrew successfully. New balance: $[balance]"를 출력

	// fmt.Printf("%.2f", balance)를 사용하여 잔액 값을 소수점 둘째 자리까지 형식화하는 것을 잊지 마세요

	_ = ownerName
	_ = initialDeposit
	_ = depositAmount
	_ = withdrawAmount
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨