Το Stringer είναι μια διεπαφή για τον ορισμό της μορφής συμβολοσειράς των τιμών.
Η διεπαφή αποτελείται από μία μόνο μέθοδο String:
type Stringer interface {
String() string
}
Οι τύποι που θέλουν να υλοποιήσουν αυτή τη διεπαφή πρέπει να έχουν μια μέθοδο String() που επιστρέφει μια φιλική προς τον άνθρωπο αναπαράσταση συμβολοσειράς του τύπου.
Το πακέτο fmt (και πολλά άλλα) θα αναζητήσει αυτή τη μέθοδο για να μορφοποιήσει και να εκτυπώσει τιμές.
Ας υποθέσουμε ότι δουλεύουμε σε μια εφαρμογή που ασχολείται με γεωγραφικές αποστάσεις μετρημένες σε διαφορετικές μονάδες.
Έχουμε ορίσει τους τύπους DistanceUnit και Distance ως εξής:
type DistanceUnit int
const (
Kilometer DistanceUnit = 0
Mile DistanceUnit = 1
)
type Distance struct {
number float64
unit DistanceUnit
}
Στο παραπάνω παράδειγμα, τα Kilometer και Mile είναι σταθερές τύπου DistanceUnit.
Αυτοί οι τύποι δεν υλοποιούν τη διεπαφή Stringer, καθώς τους λείπει η μέθοδος String.
Επομένως οι συναρτήσεις του fmt θα εκτυπώσουν τις τιμές Distance χρησιμοποιώντας την "προεπιλεγμένη μορφή" της 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!
Για να κάνουμε την έξοδο πιο κατατοπιστική, υλοποιούμε τη διεπαφή Stringer για τους τύπους DistanceUnit και Distance προσθέτοντας μια μέθοδο String σε κάθε τύπο:
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)
}
Οι συναρτήσεις του πακέτου fmt θα καλέσουν αυτές τις μεθόδους κατά τη μορφοποίηση τιμών Distance:
kmUnit := Kilometer
kmUnit.String()
// => km
mileUnit := Mile
mileUnit.String()
// => mi
dist := Distance{
number: 790.7,
unit: Kilometer,
}
dist.String()
// => 790.7 km
Η ομάδα σου εργάζεται πάνω σε μια εφαρμογή μετεωρολογίας.
Έχει ορίσει ένα API με διάφορους τύπους και σταθερές που αναπαριστούν μετεωρολογικά δεδομένα, δες το αρχείο meteorology.go.
Η αποστολή σου είναι να προσθέσεις κατάλληλες μεθόδους String σε όλους τους τύπους, ώστε να υλοποιούν τη διεπαφή Stringer.
Stringer για τον τύπο TemperatureUnit
Μετά από κάποια συζήτηση, η ομάδα συμφώνησε ότι η μονάδα θερμοκρασίας θα είναι είτε Celsius είτε Fahrenheit.
Οι τιμές θα πρέπει να μορφοποιούνται όπως φαίνεται στα παρακάτω παραδείγματα.
Κάνε τον τύπο TemperatureUnit να υλοποιεί τη διεπαφή Stringer, προσθέτοντάς του μια μέθοδο String.
Αυτή η μέθοδος πρέπει να επιστρέφει τη συμβολοσειρά "°C" αν η μονάδα θερμοκρασίας είναι Celsius ή "°F" αν η μονάδα θερμοκρασίας είναι Fahrenheit.
celsiusUnit := Celsius
fahrenheitUnit := Fahrenheit
celsiusUnit.String()
// => °C
fahrenheitUnit.String()
// => °F
fmt.Sprint(celsiusUnit)
// Output: °C
Stringer για τον τύπο Temperature
Οι τιμές θερμοκρασίας αποτελούνται από έναν ακέραιο και μια μονάδα θερμοκρασίας. Θα πρέπει να μορφοποιούνται όπως στα παρακάτω παραδείγματα.
Για να συμβεί αυτό, κάνε τον τύπο Temperature να υλοποιεί τη διεπαφή Stringer, προσθέτοντάς του μια μέθοδο String.
Αυτή η μέθοδος πρέπει να επιστρέφει μια συμβολοσειρά με την αριθμητική τιμή της θερμοκρασίας και τη μονάδα θερμοκρασίας, χωρισμένες με ένα κενό: <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 για τον τύπο SpeedUnit
Μετά από μακρές συζητήσεις, η ομάδα συμφώνησε ότι η μονάδα ταχύτητας ανέμου θα είναι είτε KmPerHour είτε MilesPerHour.
Οι τιμές θα πρέπει να μορφοποιούνται όπως στα παρακάτω παραδείγματα.
Για να συμβεί αυτό, κάνε τον τύπο SpeedUnit να υλοποιεί τη διεπαφή Stringer, προσθέτοντάς του μια μέθοδο String.
Αυτή η μέθοδος πρέπει να επιστρέφει τη συμβολοσειρά "km/h" αν η μονάδα ταχύτητας είναι χιλιόμετρα την ώρα ή "mph" αν η μονάδα ταχύτητας είναι μίλια την ώρα:
mphUnit := MilesPerHour
mphUnit.String()
// => mph
fmt.Sprint(mphUnit)
// Output: mph
kmhUnit := KmPerHour
kmhUnit.String()
// => km/h
fmt.Sprint(kmhUnit)
// Output: km/h
Stringer για τον τύπο Speed
Οι τιμές ταχύτητας ανέμου αποτελούνται από έναν ακέραιο και μια μονάδα ταχύτητας. Θα πρέπει να μορφοποιούνται όπως στο παρακάτω παράδειγμα.
Για να συμβεί αυτό, κάνε τον τύπο Speed να υλοποιεί τη διεπαφή Stringer, προσθέτοντάς του μια μέθοδο String.
Αυτή η μέθοδος πρέπει να επιστρέφει μια συμβολοσειρά με την αριθμητική τιμή της ταχύτητας και τη μονάδα ταχύτητας, χωρισμένες με ένα κενό: <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 για τον τύπο MeteorologyData
Τα μετεωρολογικά δεδομένα καθορίζουν τοποθεσία, θερμοκρασία, διεύθυνση ανέμου, ταχύτητα ανέμου και υγρασία. Θα πρέπει να μορφοποιούνται όπως στο παρακάτω παράδειγμα:
Για να συμβεί αυτό, κάνε τον τύπο MeteorologyData να υλοποιεί τη διεπαφή Stringer, προσθέτοντάς του μια μέθοδο String.
Αυτή η μέθοδος πρέπει να επιστρέφει τα μετεωρολογικά δεδομένα στην εξής μορφή:
<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
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Go με 34 έννοιες166 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.