Stringer - це інтерфейс для визначення формату рядка тексту (англ. string) для значень.
Інтерфейс складається з одного методу 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.
Цей метод має повертати рядок тексту (англ. 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 вправ та справжнє наставництво від людей, і все це безкоштовно.