Lecciones del módulo (4/5)
La interfaz Stringer
fmt.Stringer es probablemente la interfaz estándar más utilizada en todos
Biblioteca estándar de Go. Es la demostración perfecta del poder.
de pequeñas interfaces.
Definición
type Stringer interface {
String() string
}Una sola firma. Cualquier tipo que defina String() string satisface
eso. Y fmt reconoce esta interfaz: cuando pasas un valor a
fmt.Print*, si implementa Stringer, el resultado de String()
se utiliza en lugar de la representación predeterminada.
Ejemplo
type Point struct{ X, Y int }
func (p Point) String() string {
return fmt.Sprintf("(%d,%d)", p.X, p.Y)
}
fmt.Println(Point{1, 2}) // (1,2)
fmt.Printf("%v %s\n", Point{3, 4}, Point{5, 6})
// (3,4) (5,6)El mismo valor se imprime con formato personalizado en %v, %s, Println,
Sprint, log, etc. Todo con solo definir un método.
Cuando tiene sentido
- Tipos que modelan un dominio (ids, códigos, coordenadas, enumeraciones).
- Errores con una representación legible por humanos (consulte la siguiente lección sobre
error). - Tipos que registras con frecuencia y para los que deseas un formato fijo.
No para todo: si el tipo es simple y la representación por defecto Está bien, no agregues ruido.
Tipos de enumeración: patrón común con iota
type Status int
const (
OK Status = iota
WARN
ERR
)
func (s Status) String() string {
switch s {
case OK: return "OK"
case WARN: return "WARN"
case ERR: return "ERR"
default: return "UNKNOWN"
}
}
fmt.Println(OK, WARN, ERR) // OK WARN ERRSin String(), fmt.Println(OK) imprimiría 0. Con String(),
imprime el nombre simbólico. El CÓDIGOPH4
La herramienta genera este patrón automáticamente.
Cuidado con la recursividad infinita
type T int
func (t T) String() string {
return fmt.Sprintf("%d", int(t)) // OK: cast to int breaks the recursion
}Stringer en un receptor de puntero
Si String() tiene un receptor de puntero, sólo *T satisface Stringer.
Con fmt.Println(t) (un valor), Go mira el conjunto de métodos de T,
no lo encuentra y usa el formato predeterminado. Para evitar esto, **valor
El receptor ** generalmente se usa para String() (es una "vista"; no
modificar nada).
Pruébalo
Implemente String() en Point para que devuelva (X,Y).
Mostrar pista
Utilice `fmt.Sprintf` para formatear los campos.
Solución disponible después de 3 intentos
Implemente String() en un tipo Estado (int): 0 → 'OK', 1 → 'WARN', de lo contrario → 'ERR'.
Mostrar pista
Activar el valor del receptor; recuerde proporcionar un valor predeterminado.
Solución disponible después de 3 intentos
¿Qué firma debe tener el método para satisfacer fmt.Stringer?
func (x T) ??? {}Resumen
- CÓDIGOPH0.
- Su implementación cambia la forma en que
fmt.Print*representa el tipo. - Idiomatic para enumeraciones (
iota), tipos de dominio, códigos/identificadores. - Nunca llame a
fmt.Sprintf("%s", t)entdentro deString()(recursividad). - Convención: receptor de valores para
String()(sin mutación, evita "sorpresas en el conjunto de métodos").