더북(TheBook)

기본 라이브러리의 인터페이스 활용 - fmt.Stringer

다른 패키지에 정의된 인터페이스라도 인터페이스에 정의된 메서드와 서명이 같은 메서드를 제공하면 어떤 타입이든 그 인터페이스로 사용할 수 있다.

다음은 Go의 기본 라이브러리인 fmt 패키지에서 Println() 함수를 정의하는 부분이다.

func Println(a ...interface{}) (n int, err error) {
    return Fprintln(os.Stdout, a...)
}
 
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
    ...
    // fmt.Stringer 인터페이스 타입일 때 String() 메서드의 결괏값을 출력
    ...
    return
}

os.Stdout을 첫 번째 매개변수로 해서 Fprintln() 함수로 전달하고, Fprintln() 함수 내부에서는 fmt.Stringer 인터페이스로 문자열을 출력한다.

다음은 fmt 패키지에서 Stringer 인터페이스를 정의하는 부분이다.

type Stringer interface {
    String() string
}

즉, fmt.Stringer 인터페이스에 정의된 String() 메서드를 가지면 기본 출력 명령인 fmt.Println() 함수로 출력될 문자열을 지정할 수 있다.

이제 Item, DiscountItem, Renal, ItemsString() 메서드를 추가하여 fmt.Println() 함수로 각 값이 출력되게 해보자. ItemsString() 메서드에서는 fmt.Sprintf()로 각 요소의 출력 문자열을 조합하여 출력할 최종 문자열을 만든다.

func (t Item) String() string {
    return fmt.Sprintf(“[%s] %.0f”, t.name, t.Cost())
}
 
func (t DiscountItem) String() string {
    return fmt.Sprintf(”%s => %.0f(%.0f%s DC)”, t.Item.String(), t.Cost(), t.discountRate,”%”)
}
 
func (t Rental) String() string {
    return fmt.Sprintf(“[%s] %.0f”, t.name, t.Cost())
}
 
func (ts Items) String() string {
    var s []string
    for _, t := range ts {
        s = append(s, fmt.Sprint(t))
    }
    return fmt.Sprintf(”%d items. total: %.0f\n\t- %s”,
        len(ts), ts.Cost(), strings.Join(s, “\n\t- “))
}

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.