Stringer è un'interfaccia per definire il formato stringa dei valori.
L'interfaccia consiste in un unico metodo String:
type Stringer interface {
String() string
}
I tipi che vogliono implementare questa interfaccia devono avere un metodo String() che restituisce una rappresentazione del tipo in una stringa leggibile da un essere umano.
Il pacchetto fmt (e molti altri) cercherà questo metodo per formattare e stampare i valori.
Immaginiamo di lavorare a un'applicazione che gestisce distanze geografiche misurate in unità diverse.
Abbiamo definito i tipi DistanceUnit e Distance nel modo seguente:
type DistanceUnit int
const (
Kilometer DistanceUnit = 0
Mile DistanceUnit = 1
)
type Distance struct {
number float64
unit DistanceUnit
}
Nell'esempio precedente, Kilometer e Mile sono costanti di tipo DistanceUnit.
Questi tipi non implementano l'interfaccia Stringer, poiché non hanno il metodo String.
Di conseguenza, le funzioni di fmt stamperanno i valori di Distance usando il «formato predefinito» di 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!
Per rendere l'output più informativo, implementiamo l'interfaccia Stringer per i tipi DistanceUnit e Distance, aggiungendo un metodo String a ciascun 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)
}
Le funzioni del pacchetto fmt chiameranno questi metodi quando formattano i valori di Distance:
kmUnit := Kilometer
kmUnit.String()
// => km
mileUnit := Mile
mileUnit.String()
// => mi
dist := Distance{
number: 790.7,
unit: Kilometer,
}
dist.String()
// => 790.7 km
Il tuo team sta lavorando a un'applicazione di meteorologia.
Ha definito un'API con vari tipi e costanti che rappresentano dati meteorologici, vedi il file meteorology.go.
Il tuo compito è aggiungere metodi String adatti a tutti i tipi, in modo che implementino l'interfaccia Stringer.
Stringer per il tipo TemperatureUnit
Dopo qualche discussione, il team ha concordato che l'unità di temperatura sarà Celsius o Fahrenheit.
I valori dovrebbero essere formattati come mostrato negli esempi seguenti.
Fai in modo che il tipo TemperatureUnit implementi l'interfaccia Stringer aggiungendogli un metodo String.
Questo metodo deve restituire la stringa "°C" se l'unità di temperatura è Celsius o "°F" se l'unità di temperatura è Fahrenheit.
celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit
celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C
Stringer per il tipo Temperature
I valori di temperatura sono composti da un numero intero e da un'unità di temperatura. Dovrebbero essere formattati come negli esempi seguenti.
Per far sì che ciò accada, fai in modo che il tipo Temperature implementi l'interfaccia Stringer aggiungendogli un metodo String.
Questo metodo dovrebbe restituire una stringa con il valore numerico della temperatura e l'unità di temperatura separati da uno spazio: <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 per il tipo SpeedUnit
Dopo lunghe discussioni, il team ha concordato che l'unità di velocità del vento sarà KmPerHour o MilesPerHour.
I valori dovrebbero essere formattati come negli esempi seguenti.
Per far sì che ciò accada, fai in modo che il tipo SpeedUnit implementi l'interfaccia Stringer aggiungendogli un metodo String.
Questo metodo deve restituire la stringa "km/h" se l'unità di velocità è chilometri orari o "mph" se l'unità di velocità è miglia orarie:
mphUnit := MilesPerHour
mphUnit.String()
// => mph
fmt.Sprint(mphUnit)
// Output: mph
kmhUnit := KmPerHour
kmhUnit.String()
// => km/h
fmt.Sprint(kmhUnit)
// Output: km/h
Stringer per Speed
I valori di velocità del vento sono composti da un numero intero e da un'unità di velocità. Dovrebbero essere formattati come nell'esempio seguente.
Per far sì che ciò accada, fai in modo che il tipo Speed implementi l'interfaccia Stringer aggiungendogli un metodo String.
Questo metodo dovrebbe restituire una stringa con il valore numerico della velocità e l'unità di velocità separati da uno spazio: <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 per il tipo MeteorologyData
I dati meteorologici specificano posizione, temperatura, direzione del vento, velocità del vento e umidità. Dovrebbero essere formattati come nell'esempio seguente:
Per far sì che ciò accada, fai in modo che il tipo MeteorologyData implementi l'interfaccia Stringer aggiungendogli un metodo String.
Questo metodo dovrebbe restituire i dati meteorologici nel formato seguente:
<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
Iscriviti a Exercism per imparare e padroneggiare Go con 34 concetti166 esercizi e il mentoring di persone reali, tutto gratis.