Треки
/
Go
Go
/
Вправи
/
Метеорологія
Метеорологія

Метеорологія

Навчальна вправа

Вступ

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.

1. Реалізуйте інтерфейс 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

2. Реалізуйте інтерфейс 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

3. Реалізуйте інтерфейс 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

4. Реалізуйте інтерфейс 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

5. Реалізуйте інтерфейс 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
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Go Exercism

Час розпочати Метеорологія?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Go, а також 34 концепції166 вправ та справжнє наставництво від людей, і все це безкоштовно.