fmt.Stringer 인터페이스
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 107개 중 75번째.
fmt.Stringer 인터페이스는 출력할 때 타입이 어떻게 표시되는지를 제어합니다. Go에서 가장 흔히 구현되는 인터페이스 중 하나이며, fmt 패키지에 정의되어 있습니다.
type Stringer interface {
String() string
}fmt.Println, %v를 사용하는 fmt.Printf 또는 이와 유사한 함수에 값을 전달하면 Go는 해당 타입이 Stringer를 구현하는지 확인합니다. 구현한다면 Go는 텍스트 표현을 얻기 위해 String() 메서드를 호출합니다.
type Temperature struct {
Celsius float64
}
func (t Temperature) String() string {
return fmt.Sprintf("%.1f°C", t.Celsius)
}
func main() {
temp := Temperature{Celsius: 23.5}
fmt.Println(temp) // 23.5°C
}String() 메서드가 없다면 출력 시 기본 구조체 형식인 {23.5}이 표시됩니다. Stringer를 구현하면 해당 타입이 자신을 표시하는 방식을 정확하게 제어할 수 있습니다.
이는 원시 필드 값만으로는 의미가 명확하게 전달되지 않는 타입에 특히 유용합니다. Duration 타입은 원시 나노초를 표시하는 대신 "2h 30m"으로 표시할 수 있고, User 타입은 모든 필드 대신 형식이 지정된 이름을 표시할 수 있습니다.
챌린지
쉬움사용자에게 친숙한 형식으로 duration을 표시하는 time tracking system을 만들어 봅시다! 사용자 지정 타입이 출력될 때 어떻게 표시되는지 제어하도록 fmt.Stringer interface를 Implement합니다.
코드를 두 개의 파일로 구성합니다.
duration.go: 사용자 지정 문자열 표현을 사용하는 time 관련 타입을 정의합니다.총 minutes 수를 정수로 저장하는
Durationstruct를 Create합니다. 150 minutes일 때2h 30m, 45 minutes일 때0h 45m처럼 출력 시 읽기 쉬운 형식으로 표시되도록String()method를 Implement합니다. hours와 minutes는 항상 표시되어야 합니다.Name(string) 및Time(Duration) fields를 가진Taskstruct를 Create합니다. duration이 자체 String method를 사용하도록 Task에String()을 Implement하여[Name]: [duration]형식으로 표시합니다.main.go: tasks와 해당 duration을 Build하고 표시합니다.tasks의 수를 Read한 다음, 각 task에 대해 이름과 duration을 minutes 단위로 Read합니다. Task instances를 Create하고
fmt.Println을 사용하여 각 항목을 직접 Print합니다. 그러면 Stringer interface가 formatting을 자동으로 처리합니다.모든 tasks를 Print한 후, 모든 tasks의 total time을 다음 형식으로 calculate하고 Print합니다.
Total: [duration]
다음 input이 제공됩니다.
- Line 1: tasks의 number
- 이후 lines: Task name과 minutes (task당 두 lines)
예를 들어 다음이 주어졌을 때:
3
Code Review
90
Meeting
45
Documentation
120output은 다음과 같아야 합니다.
Code Review: 1h 30m
Meeting: 0h 45m
Documentation: 2h 0m
Total: 4h 15m또한 다음이 주어졌을 때:
2
Design
180
Testing
65output은 다음과 같아야 합니다.
Design: 3h 0m
Testing: 1h 5m
Total: 4h 5mStringer를 Implement하면 사용자의 타입이 Go의 printing functions와 seamless하게 통합됩니다. {90}과 같은 raw struct fields가 표시되는 대신, 사용자가 이해하기 쉬운 의미 있는 output을 얻을 수 있습니다.
직접 해보기
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// 작업 수 읽기
line, _ := reader.ReadString('\n')
numTasks, _ := strconv.Atoi(strings.TrimSpace(line))
// TODO: 작업을 저장할 슬라이스 생성
// TODO: 총 분 추적
for i := 0; i < numTasks; i++ {
// 작업 이름 읽기
name, _ := reader.ReadString('\n')
name = strings.TrimSpace(name)
// 분 단위로 작업 소요 시간 읽기
minutesLine, _ := reader.ReadString('\n')
minutes, _ := strconv.Atoi(strings.TrimSpace(minutesLine))
// TODO: name과 Duration으로 Task 생성
// TODO: 작업 출력 (fmt.Println이 Stringer 인터페이스를 사용함)
// TODO: 총계에 분 추가
_ = name
_ = minutes
}
// TODO: "Total: Xh Ym" 형식으로 총 소요 시간 출력
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서11표준 라이브러리 & OOP
io.Reader & io.Writersort.Interfacefmt.Stringer 인터페이스encoding/json과 구조체http.Handler 인터페이스요약 - REST API 모델직접 연습해 보세요: 온라인 Go 컴파일러