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 类型的常量。
这些类型没有实现 Stringer 接口,因为它们缺少 String 方法。
因此,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!
为了让输出信息更丰富,我们给 DistanceUnit 和 Distance 类型各添加一个 String 方法,从而让它们实现 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