Stringer는 값의 문자열 형식을 정의하기 위한 인터페이스예요.
이 인터페이스는 단 하나의 String 메서드로 이루어져 있어요:
type Stringer interface {
String() string
}
이 인터페이스를 구현하려는 타입은, 해당 타입을 사람이 읽기 쉬운 문자열로 표현한 값을 반환하는 String() 메서드를 가져야 해요.
fmt 패키지(그리고 다른 많은 패키지)는 값을 포맷해서 출력할 때 이 메서드를 찾아요.
여러 단위로 측정하는 지리적 거리를 다루는 애플리케이션을 만들고 있다고 가정해 봐요.
DistanceUnit과 Distance 타입을 다음과 같이 정의했어요:
type DistanceUnit int
const (
Kilometer DistanceUnit = 0
Mile DistanceUnit = 1
)
type Distance struct {
number float64
unit DistanceUnit
}
위 예제에서 Kilometer와 Mile은 DistanceUnit 타입의 상수예요.
이 타입들은 String 메서드가 없기 때문에 Stringer 인터페이스를 구현하지 않아요.
따라서 fmt 함수들은 Go의 "기본 형식"으로 Distance 값을 출력해요:
mileUnit := Mile
fmt.Sprint(mileUnit)
// => 1
// The result is '1' because that is the underlying value of the 'Mile' constant (see constant declarations above)
dist := Distance{number: 790.7, unit: Kilometer}
fmt.Sprint(dist)
// => {790.7 0}
// not a very useful output!
출력을 좀 더 알기 쉽게 만들기 위해, 각 타입에 String 메서드를 추가해서 DistanceUnit과 Distance 타입에 Stringer 인터페이스를 구현해 볼게요:
func (sc DistanceUnit) String() string {
units := []string{"km", "mi"}
return units[sc]
}
func (d Distance) String() string {
return fmt.Sprintf("%v %v", d.number, d.unit)
}
fmt 패키지 함수들은 Distance 값을 포맷할 때 이 메서드들을 호출해요:
kmUnit := Kilometer
kmUnit.String()
// => km
mileUnit := Mile
mileUnit.String()
// => mi
dist := Distance{
number: 790.7,
unit: Kilometer,
}
dist.String()
// => 790.7 km