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

챌린지

쉬움

시간을 사람이 읽기 쉬운 형식으로 표시하는 시간 추적 시스템을 만들어 봅시다! fmt.Stringer 인터페이스를 구현하여 사용자 정의 타입이 출력될 때 어떻게 보일지 제어하게 됩니다.

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

  • duration.go: 사용자 정의 문자열 표현을 가진 시간 관련 타입을 정의합니다.

    전체 분(minutes)을 정수로 저장하는 Duration 구조체를 만드세요. String() 메서드를 구현하여 출력 시 150분의 경우 2h 30m, 45분의 경우 0h 45m과 같이 읽기 쉬운 형식으로 표시되도록 하세요. 시간(Hours)과 분(minutes)은 항상 표시되어야 합니다.

    Name (string)과 Time (Duration) 필드를 가진 Task 구조체를 만드세요. Task에 String()을 구현하여 [Name]: [duration] 형식으로 표시되도록 하세요. 여기서 duration은 자체 String 메서드를 사용합니다.

  • main.go: 작업과 해당 기간을 생성하고 표시합니다.

    작업의 개수를 읽은 다음, 각 작업에 대해 이름과 분 단위의 기간을 읽습니다. Task 인스턴스를 생성하고 fmt.Println을 사용하여 각 인스턴스를 직접 출력하세요. Stringer 인터페이스가 자동으로 포맷팅을 처리할 것입니다.

    모든 작업을 출력한 후, 모든 작업의 총 시간을 다음 형식으로 계산하여 출력하세요:

    Total: [duration]

다음 입력이 제공됩니다:

  • Line 1: 작업의 개수
  • 이어지는 줄들: 작업 이름과 분 (작업당 두 줄)

예를 들어, 다음과 같이 주어지면:

3
Code Review
90
Meeting
45
Documentation
120

출력은 다음과 같아야 합니다:

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

그리고 다음과 같이 주어지면:

2
Design
180
Testing
65

출력은 다음과 같아야 합니다:

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

Stringer를 구현함으로써, 여러분의 타입은 Go의 출력 함수와 원활하게 통합됩니다. {90}과 같은 가공되지 않은 구조체 필드 대신, 사용자에게 의미 있는 출력을 제공할 수 있습니다.

치트 시트

fmt.Stringer 인터페이스는 타입을 출력할 때 어떻게 표시될지를 제어합니다:

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를 구현함으로써 타입이 자신을 표현하는 방식을 정확하게 제어할 수 있으며, 출력을 더 의미 있고 사용자 친화적으로 만들 수 있습니다.

직접 해보기

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: 이름과 Duration을 가진 Task 생성
		// TODO: 작업 출력 (fmt.Println은 Stringer 인터페이스를 사용함)
		// TODO: 총합에 분 추가
		_ = name
		_ = minutes
	}

	// TODO: 총 소요 시간을 "Total: Xh Ym" 형식으로 출력
}
quiz icon실력 점검

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

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