Menu
Coddy logo textTech

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 타입은 모든 필드 대신 형식이 지정된 이름을 표시할 수 있습니다.

challenge icon

챌린지

쉬움

사용자에게 친숙한 형식으로 duration을 표시하는 time tracking system을 만들어 봅시다! 사용자 지정 타입이 출력될 때 어떻게 표시되는지 제어하도록 fmt.Stringer interface를 Implement합니다.

코드를 두 개의 파일로 구성합니다.

  • duration.go: 사용자 지정 문자열 표현을 사용하는 time 관련 타입을 정의합니다.

    총 minutes 수를 정수로 저장하는 Duration struct를 Create합니다. 150 minutes일 때 2h 30m, 45 minutes일 때 0h 45m처럼 출력 시 읽기 쉬운 형식으로 표시되도록 String() method를 Implement합니다. hours와 minutes는 항상 표시되어야 합니다.

    Name(string) 및 Time(Duration) fields를 가진 Task struct를 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
120

output은 다음과 같아야 합니다.

Code Review: 1h 30m
Meeting: 0h 45m
Documentation: 2h 0m
Total: 4h 15m

또한 다음이 주어졌을 때:

2
Design
180
Testing
65

output은 다음과 같아야 합니다.

Design: 3h 0m
Testing: 1h 5m
Total: 4h 5m

Stringer를 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" 형식으로 총 소요 시간 출력
}
quiz icon실력 점검

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

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

직접 연습해 보세요: 온라인 Go 컴파일러