The Stringer Interface
Implementing Stringer
The standard library's fmt.Stringer interface requires exactly one method, String() string. Any type that implements it gets used automatically whenever it's printed with Println, Printf's %v, or similar.
Example: Implementing Stringer
package main
import "fmt"
type Point struct {
X, Y int
}
func (p Point) String() string {
return fmt.Sprintf("(%d, %d)", p.X, p.Y)
}
func main() {
p := Point{3, 4}
fmt.Println(p)
}
Login to try C/C++/Java/PHP code in the editor
Without vs With Stringer
A struct without a String() method prints its default, somewhat verbose field-by-field representation, while implementing Stringer gives you full control over exactly how it reads when printed.
Example: Without vs With Stringer
package main
import "fmt"
type Status int
const (
Active Status = iota
Inactive
)
func (s Status) String() string {
if s == Active {
return "Active"
}
return "Inactive"
}
func main() {
fmt.Println(Active)
fmt.Println(Inactive)
}
Login to try C/C++/Java/PHP code in the editor
Avoiding Infinite Recursion
A common mistake is calling fmt.Sprintf("%v", p) on the receiver p inside its own String() method -- since %v triggers String() again, this recurses forever. Building the string from individual fields avoids the problem.
Note: Always build the String() output from the struct's individual fields, never the receiver as a whole.
Example: Avoiding Infinite Recursion
package main
import "fmt"
type Temp struct {
Celsius float64
}
func (t Temp) String() string {
return fmt.Sprintf("%.1f°C", t.Celsius) // uses the field, not t itself
}
func main() {
fmt.Println(Temp{Celsius: 21.5})
}
Login to try C/C++/Java/PHP code in the editor
- Naming the method something other than exactly 'String() string' -- fmt only recognizes that exact signature for the Stringer interface.
- Accidentally causing infinite recursion by calling fmt.Sprintf("%v", t) on the receiver itself inside its own String() method.
- Forgetting that a String() method defined with a pointer receiver only applies when printing a pointer to the type, not the value itself.
- The fmt.Stringer interface requires one method: String() string.
- Implementing it lets fmt.Println and %v automatically use your custom, readable representation.
- Calling fmt formatting functions on the receiver itself inside String() causes infinite recursion -- format the underlying fields instead.
- Stringer is a great example of Go's small, implicit interfaces in everyday use.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: