Menu
Coddy logo textTech

Stringer 및 Error 인터페이스

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

Go의 표준 라이브러리는 여러분이 끊임없이 사용하게 될 두 가지 인터페이스를 정의합니다: fmt.Stringererror입니다. 둘 다 여러분의 타입이 Go의 내장 기능과 강력하게 통합될 수 있도록 해주는 단순한 단일 메서드 인터페이스입니다.

Stringer 인터페이스는 fmt 패키지에 정의되어 있으며, 단 하나의 메서드만을 필요로 합니다:

type Stringer interface {
    String() string
}

당신의 타입에 String()을 구현하면, fmt.Println과 같은 함수들이 당신의 값을 표시할 때 이를 자동으로 사용합니다:

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s (%d years old)", p.Name, p.Age)
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    fmt.Println(p)  // Alice (30세)
}

error 인터페이스는 마찬가지로 간단하며, 문자열을 반환하는 Error() 메서드를 요구합니다:

type error interface {
    Error() string
}

Error() 메서드를 가진 어떠한 타입이라도 Go에서 에러 값으로 사용될 수 있습니다. 이를 통해 추가적인 컨텍스트를 포함하는 사용자 정의 에러 타입을 만들 수 있습니다:

type ValidationError struct {
    Field   string
    Message string
}

func (e ValidationError) Error() string {
    return fmt.Sprintf("%s: %s", e.Field, e.Message)
}

func main() {
    err := ValidationError{Field: "email", Message: "invalid format"}
    fmt.Println(err)  // email: 유효하지 않은 형식
}

이 두 인터페이스는 암시적 구현을 통해 강력한 동작을 가능하게 하는 작고 집중된 인터페이스라는 Go의 철학을 잘 보여줍니다.

challenge icon

챌린지

쉬움

Stringererror 인터페이스를 모두 사용하여 읽기 쉬운 출력과 의미 있는 에러 처리를 제공하는 온도 모니터링 시스템을 구축해 보겠습니다.

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

  • temperature.go: Value (float64)와 Unit (string) 필드를 가진 Temperature 구조체를 생성하세요. 출력될 때 사람이 읽기 쉬운 형식으로 온도를 표시하도록 String() 메서드를 구현하세요. 또한 Temp (float64)와 Reason (string) 필드를 가진 TemperatureError 구조체를 생성하고, 설명적인 에러 메시지를 제공하도록 Error() 메서드를 구현하세요.
  • main.go: Temperature를 인자로 받고 온도가 유효하지 않으면 에러를 반환하는 ValidateTemperature 함수를 생성하세요. 온도가 절대 영도(섭씨 -273.15, 화씨 -459.67) 미만이면 유효하지 않은 것으로 간주합니다. 유효한 경우 함수는 nil을 반환합니다. 입력에서 온도 데이터를 읽고, Temperature를 생성하고, 유효성을 검사한 후 적절한 출력을 프린트하세요.

다음과 같은 입력이 제공됩니다:

  • Line 1: 온도 값 (float)
  • Line 2: 단위 (섭씨의 경우 C 또는 화씨의 경우 F)

String() 메서드는 다음 형식을 반환해야 합니다:

[Value] degrees [Unit]

여기서 Unit은 입력에 따라 "Celsius" 또는 "Fahrenheit"라는 전체 단어여야 합니다.

Error() 메서드는 다음 형식을 반환해야 합니다:

invalid temperature [Temp]: [Reason]

온도가 유효하면 fmt.Println을 사용하여 Temperature를 출력하세요 (이때 String() 메서드가 사용됩니다). 유효하지 않으면 에러를 출력하세요 (이때 Error() 메서드가 사용됩니다).

예를 들어, 25.5C가 주어지면 출력은 다음과 같아야 합니다:

25.5 degrees Celsius

-500F가 주어지면 출력은 다음과 같아야 합니다:

invalid temperature -500: below absolute zero

온도가 너무 낮을 때의 사유(reason)로 "below absolute zero"를 사용하세요.

치트 시트

Go의 표준 라이브러리는 두 가지 필수 인터페이스인 fmt.Stringererror를 정의합니다.

Stringer 인터페이스

fmt 패키지의 Stringer 인터페이스는 하나의 메서드를 요구합니다:

type Stringer interface {
    String() string
}

사용자 정의 타입에 String()을 구현하면, fmt.Println과 같은 함수들이 자동으로 이를 사용합니다:

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s (%d years old)", p.Name, p.Age)
}

func main() {
    p := Person{Name: "Alice", Age: 30}
    fmt.Println(p)  // Alice (30 years old)
}

error 인터페이스

error 인터페이스는 문자열을 반환하는 Error() 메서드를 요구합니다:

type error interface {
    Error() string
}

Error() 메서드가 있는 모든 타입은 에러 값으로 사용될 수 있으며, 이를 통해 추가적인 컨텍스트를 포함하는 사용자 정의 에러 타입을 만들 수 있습니다:

type ValidationError struct {
    Field   string
    Message string
}

func (e ValidationError) Error() string {
    return fmt.Sprintf("%s: %s", e.Field, e.Message)
}

func main() {
    err := ValidationError{Field: "email", Message: "invalid format"}
    fmt.Println(err)  // email: invalid format
}

직접 해보기

package main

import (
	"fmt"
)

// ValidateTemperature는 온도가 유효한지 확인합니다
// 온도가 절대 영도보다 낮으면 에러를 반환합니다
// 절대 영도: 섭씨(Celsius)는 -273.15, 화씨(Fahrenheit)는 -459.67
func ValidateTemperature(t Temperature) error {
	// TODO: 검증 로직 구현
	// 단위에 따라 온도가 절대 영도보다 낮은지 확인합니다
	// 유효하지 않으면 TemperatureError를 반환하고, 유효하면 nil을 반환합니다
	return nil
}

func main() {
	var value float64
	var unit string
	fmt.Scanln(&value)
	fmt.Scanln(&unit)

	// TODO: 입력값으로 Temperature 구조체 생성

	// TODO: ValidateTemperature를 사용하여 온도 검증

	// TODO: 에러가 발생하면 에러를 출력
	// 그렇지 않으면 온도를 출력 (String() 메서드가 사용됨)
}
quiz icon실력 점검

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

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