Stringer es una interfaz para definir el formato string de los valores.
La interfaz consta de un único método String:
type Stringer interface {
String() string
}
Los tipos que quieran implementar esta interfaz deben tener un método String() que devuelva una representación del tipo legible para las personas.
El paquete fmt (y muchos otros) buscará este método para dar formato e imprimir valores.
Supongamos que trabajamos en una aplicación que maneja distancias geográficas medidas en distintas unidades.
Hemos definido los tipos DistanceUnit y Distance de la siguiente manera:
type DistanceUnit int
const (
Kilometer DistanceUnit = 0
Mile DistanceUnit = 1
)
type Distance struct {
number float64
unit DistanceUnit
}
En el ejemplo anterior, Kilometer y Mile son constantes de tipo DistanceUnit.
Estos tipos no implementan la interfaz Stringer, ya que no tienen el método String.
Por lo tanto, las funciones de fmt imprimirán los valores de Distance usando el «formato predeterminado» de Go:
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!
Para que la salida sea más informativa, implementamos la interfaz Stringer para los tipos DistanceUnit y Distance añadiendo un método String a cada tipo:
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)
}
Las funciones del paquete fmt llamarán a estos métodos al dar formato a los valores de Distance:
kmUnit := Kilometer
kmUnit.String()
// => km
mileUnit := Mile
mileUnit.String()
// => mi
dist := Distance{
number: 790.7,
unit: Kilometer,
}
dist.String()
// => 790.7 km
Tu equipo trabaja en una aplicación de meteorología.
Han definido una API con varios tipos y constantes que representan datos meteorológicos; consulta el archivo meteorology.go.
Tu tarea es añadir métodos String adecuados a todos los tipos para que implementen la interfaz Stringer.
Stringer para el tipo TemperatureUnit
Tras un pequeño debate, el equipo ha acordado que la unidad de temperatura será Celsius o Fahrenheit.
Los valores deben formatearse como se muestra en los ejemplos siguientes.
Haz que el tipo TemperatureUnit implemente la interfaz Stringer añadiéndole un método String.
Este método debe devolver el string "°C" si la unidad de temperatura es Celsius o "°F" si la unidad de temperatura es Fahrenheit.
celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit
celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C
Stringer para el tipo Temperature
Los valores de temperatura constan de un número entero y una unidad de temperatura. Deben formatearse como en los ejemplos siguientes.
Para conseguirlo, haz que el tipo Temperature implemente la interfaz Stringer añadiéndole un método String.
Este método debe devolver un string con el valor numérico de la temperatura y la unidad de temperatura separados por un espacio: <temperature> <unit>:
celsiusTemp := Temperature{
degree: 21,
unit: Celsius,
}
celsiusTemp.String()
// => 21 °C
fmt.Sprint(celsiusTemp)
// Output: 21 °C
fahrenheitTemp := Temperature{
degree: 75,
unit: Fahrenheit,
}
fahrenheitTemp.String()
// => 75 °F
fmt.Sprint(fahrenheitTemp)
// Output: 75 °F
Stringer para el tipo SpeedUnit
Tras largos debates, el equipo ha acordado que la unidad de velocidad del viento será KmPerHour o MilesPerHour.
Los valores deben formatearse como en los ejemplos siguientes.
Para conseguirlo, haz que el tipo SpeedUnit implemente la interfaz Stringer añadiéndole un método String.
Este método debe devolver el string "km/h" si la unidad de velocidad es kilómetros por hora o "mph" si la unidad de velocidad es millas por hora:
mphUnit := MilesPerHour
mphUnit.String()
// => mph
fmt.Sprint(mphUnit)
// Output: mph
kmhUnit := KmPerHour
kmhUnit.String()
// => km/h
fmt.Sprint(kmhUnit)
// Output: km/h
Stringer para Speed
Los valores de velocidad del viento constan de un número entero y una unidad de velocidad. Deben formatearse como en el ejemplo siguiente.
Para conseguirlo, haz que el tipo Speed implemente la interfaz Stringer añadiéndole un método String.
Este método debe devolver un string con el valor numérico de la velocidad y la unidad de velocidad separados por un espacio: <speed> <unit>:
windSpeedNow := Speed{
magnitude: 18,
unit: KmPerHour,
}
windSpeedNow.String()
// => 18 km/h
fmt.Sprintf(windSpeedNow)
// Output: 18 km/h
windSpeedYesterday := Speed{
magnitude: 22,
unit: MilesPerHour,
}
windSpeedYesterday.String()
// => 22 mph
fmt.Sprint(windSpeedYesterday)
// Output: 22 mph
Stringer para el tipo MeteorologyData
Los datos meteorológicos especifican la ubicación, la temperatura, la dirección del viento, la velocidad del viento y la humedad. Deben formatearse como en el ejemplo siguiente:
Para conseguirlo, haz que el tipo MeteorologyData implemente la interfaz Stringer añadiéndole un método String.
Este método debe devolver los datos meteorológicos con el siguiente formato:
<location>: <temperature>, Wind <wind_direction> at <wind_speed>, <humidity>% Humidity
sfData := MeteorologyData{
location: "San Francisco",
temperature: Temperature{
degree: 57,
unit: Fahrenheit
},
windDirection: "NW",
windSpeed: Speed{
magnitude: 19,
unit: MilesPerHour
},
humidity: 60
}
sfData.String()
// => San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
fmt.Sprint(sfData)
// Output: San Francisco: 57 °F, Wind NW at 19 mph, 60% Humidity
Regístrate en Exercism para aprender y dominar Go con 34 conceptos165 ejercicios y mentoría humana real, todo gratis.