go 35 lines · 5 steps

Implementing fmt.Stringer in Go

How custom String methods let your types control their own formatted output and compose cleanly.

Explained by highlit
1package geometry
2 
3import "fmt"
4 
5// Point represents a coordinate in 2D space.
6type Point struct {
7 X, Y int
8}
9 
10// String satisfies the fmt.Stringer interface, controlling how a Point
11// is rendered by fmt verbs like %v, %s, and by Println.
12func (p Point) String() string {
13 return fmt.Sprintf("(%d, %d)", p.X, p.Y)
14}
15 
16// Color models an RGB color.
17type Color struct {
18 R, G, B uint8
19}
20 
21func (c Color) String() string {
22 return fmt.Sprintf("#%02X%02X%02X", c.R, c.G, c.B)
23}
24 
25// Shape composes other Stringer values; its own String method delegates
26// to them, demonstrating how Stringer composes naturally.
27type Shape struct {
28 Name string
29 Origin Point
30 Fill Color
31}
32 
33func (s Shape) String() string {
34 return fmt.Sprintf("%s at %v filled %v", s.Name, s.Origin, s.Fill)
35}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Any type with a String() string method automatically satisfies fmt.Stringer and controls its own rendering under %v, %s, and Println.
  2. 2Implementing Stringer once means every fmt verb and logging call formats your type consistently, without callers writing format strings.
  3. 3Stringer composes: an outer type's String method can use %v on its Stringer fields, so formatting nests automatically.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Implementing fmt.Stringer in Go — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code