Stringer 및 Error 인터페이스
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 32번째.
Go의 표준 라이브러리는 여러분이 끊임없이 사용하게 될 두 가지 인터페이스를 정의합니다: fmt.Stringer와 error입니다. 둘 다 여러분의 타입이 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의 철학을 잘 보여줍니다.
챌린지
쉬움Stringer와 error 인터페이스를 모두 사용하여 읽기 쉬운 출력과 의미 있는 에러 처리를 제공하는 온도 모니터링 시스템을 구축해 보겠습니다.
코드는 두 개의 파일로 구성됩니다:
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.5와 C가 주어지면 출력은 다음과 같아야 합니다:
25.5 degrees Celsius-500과 F가 주어지면 출력은 다음과 같아야 합니다:
invalid temperature -500: below absolute zero온도가 너무 낮을 때의 사유(reason)로 "below absolute zero"를 사용하세요.
치트 시트
Go의 표준 라이브러리는 두 가지 필수 인터페이스인 fmt.Stringer와 error를 정의합니다.
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() 메서드가 사용됨)
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서