Lección 4 · 4 de 20
Stringer y formato de sus tipos · Go
Decida cómo se escriben sus tipos en Go con el método String (fmt.Stringer) y vea qué hacen %v, %+v, %#v, %d y los anchos con ellos.

fmt busca en cada valor un método String() string; si lo tiene, el valor cumple la interfaz `fmt.Stringer` y se escribe con él. Status es un entero con constantes creadas con `iota` (0, 1, 2), y su String las traduce con un array: Shipped sale como shipped, no como 1.
Money guarda céntimos en un int64 para no arrastrar errores de redondeo, y su String los escribe como 259.99 EUR. Por eso fmt.Println(o.Status, o.Total) da textos legibles sin ninguna conversión a mano.
Con un struct, %v escribe los campos entre llaves y usa el String de cada uno: {1042 259.99 EUR shipped}. `%+v` añade los nombres de los campos, muy útil para depurar. `%#v` escribe sintaxis de Go (main.Order{ID:1042, Total:25999, Status:1}) y no llama a String.
Solo los verbos de texto (%v, %s, %q, %x) llaman a String. Con `%d` sale el número que hay debajo: 1 25999. Los anchos funcionan sobre el texto que devuelve String: %-12s alinea a la izquierda y %12v, a la derecha.
Una trampa: dentro de String no escriba el propio valor con %v o %s, porque fmt volvería a llamar a String sin fin. Money usa %d, que no lo llama, así que no hay problema.
Código · main.go
package mainimport "fmt"type Status intconst ( Pending Status = iota Shipped Delivered)// String makes Status a fmt.Stringer: %v and %s call it.func (s Status) String() string { return [...]string{"pending", "shipped", "delivered"}[s] }type Money int64 // amount in centsfunc (m Money) String() string { return fmt.Sprintf("%d.%02d EUR", m/100, m%100) }type Order struct { ID int Total Money Status Status}func main() { o := Order{ID: 1042, Total: 25999, Status: Shipped} fmt.Println("status:", o.Status, "| total:", o.Total) fmt.Printf("%v\n", o) fmt.Printf("%+v\n", o) fmt.Printf("%#v\n", o) // Go syntax: String is not used fmt.Printf("%d %d\n", o.Status, o.Total) // %d prints the plain number fmt.Printf("|%-12s|%12v|\n", Delivered, o.Total) // width and alignment}Salida · go run main.go
status: shipped | total: 259.99 EUR
{1042 259.99 EUR shipped}
{ID:1042 Total:259.99 EUR Status:shipped}
main.Order{ID:1042, Total:25999, Status:1}
1 25999
|delivered | 259.99 EUR|Para recordar
- Un tipo con
String() stringes unfmt.Stringer. %vy%susanString;%describe el número.%+vañade los nombres de los campos;%#v, la sintaxis de Go.- Los anchos (
%-12s) se aplican al texto deString. - Dentro de
String, no formatee el propio valor con%v.
Ejercicio
Añada un estado Cancelled a las constantes y a la tabla de String, y cambie el pedido a ese estado. Después escriba fmt.Printf("%q\n", o.Status) y observe que %q también usa String.