Stringer é uma interface para definir o formato em string de valores.
A interface consiste em um único método String:
type Stringer interface {
String() string
}
Os tipos que quiserem implementar essa interface precisam ter um método String() que retorne uma representação do tipo em string, amigável para humanos.
O pacote fmt (e muitos outros) procura esse método para formatar e imprimir valores.
Suponha que estejamos trabalhando em uma aplicação que lida com distâncias geográficas medidas em unidades diferentes.
Definimos os tipos DistanceUnit e Distance da seguinte forma:
type DistanceUnit int
const (
Kilometer DistanceUnit = 0
Mile DistanceUnit = 1
)
type Distance struct {
number float64
unit DistanceUnit
}
No exemplo acima, Kilometer e Mile são constantes do tipo DistanceUnit.
Esses tipos não implementam a interface Stringer, pois não têm o método String.
Por isso, as funções de fmt vão imprimir valores de Distance usando o "formato padrão" do 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 deixar a saída mais informativa, implementamos a interface Stringer para os tipos DistanceUnit e Distance, adicionando um 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)
}
As funções do pacote fmt chamam esses métodos ao formatar 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
Sua equipe está trabalhando em uma aplicação de meteorologia.
Eles definiram uma API com vários tipos e constantes que representam dados meteorológicos, veja o arquivo meteorology.go.
Sua tarefa é adicionar métodos String adequados a todos os tipos para que eles implementem a interface Stringer.
Stringer para o tipo TemperatureUnit
Depois de algumas discussões, a equipe concordou que a unidade de temperatura será Celsius ou Fahrenheit.
Os valores devem ser formatados como mostrado nos exemplos abaixo.
Faça o tipo TemperatureUnit implementar a interface Stringer adicionando um método String a ele.
Esse método deve retornar a string "°C" se a unidade de temperatura for Celsius ou "°F" se a unidade de temperatura for Fahrenheit.
celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit
celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C
Stringer para o tipo Temperature
Os valores de temperatura consistem em um número inteiro e uma unidade de temperatura. Eles devem ser formatados como nos exemplos abaixo.
Para isso, faça o tipo Temperature implementar a interface Stringer adicionando um método String a ele.
Esse método deve retornar uma string com o valor numérico da temperatura e a unidade de temperatura separados por um espaço: <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 o tipo SpeedUnit
Depois de longas discussões, a equipe concordou que a unidade de velocidade do vento será KmPerHour ou MilesPerHour.
Os valores devem ser formatados como nos exemplos abaixo.
Para isso, faça o tipo SpeedUnit implementar a interface Stringer adicionando um método String a ele.
Esse método deve retornar a string "km/h" se a unidade de velocidade for quilômetros por hora ou "mph" se a unidade de velocidade for milhas 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
Os valores de velocidade do vento consistem em um número inteiro e uma unidade de velocidade. Eles devem ser formatados como no exemplo abaixo.
Para isso, faça o tipo Speed implementar a interface Stringer adicionando um método String a ele.
Esse método deve retornar uma string com o valor numérico da velocidade e a unidade de velocidade separados por um espaço: <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 o tipo MeteorologyData
Os dados meteorológicos especificam localização, temperatura, direção do vento, velocidade do vento e umidade. Devem ser formatados como no exemplo abaixo:
Para isso, faça o tipo MeteorologyData implementar a interface Stringer adicionando um método String a ele.
Esse método deve retornar os dados meteorológicos no seguinte 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
Crie sua conta no Exercism para aprender e dominar Go com 34 conceitos166 exercícios e mentoria humana de verdade, tudo de graça.