Треки
/
Go
Go
/
Вправи
/
Сортувальна кімната
Сортувальна кімната

Сортувальна кімната

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

Вступ

Перетворення типів

Go вимагає явного перетворення між різними типами. Перетворення між типами (також відоме як приведення типів) виконується за допомогою функції з назвою типу, до якого потрібно перетворити. Наприклад, щоб перетворити int на float64, потрібно зробити таке:

var x int = 42 // x has type int
f := float64(x) // f has type float64 (ie. 42.0)

Перетворення між примітивними типами та рядками тексту

Існує пакет strconv для перетворення між примітивними типами (як-от int) і рядками тексту (англ. string).

import "strconv"

var intString string = "42"
var i, err = strconv.Atoi(intString)

var number int = 12
var s string = strconv.Itoa(number)

Твердження типу

Інтерфейси в Go можуть створювати неоднозначність щодо базового типу. Твердження типу дає змогу вилучити конкретне значення, що лежить в основі значення інтерфейсу, за допомогою такого синтаксису: interfaceVariable.(concreteType).

Наприклад:

var input any = 12
number := input.(int)

ПРИМІТКА: це спричинить паніку, якщо змінна інтерфейсу не містить значення конкретного типу.

Ми можемо перевірити, чи містить значення інтерфейсу конкретний тип, скориставшись обома поверненими значеннями твердження типу: значенням, що лежить в основі, і булевим значенням (англ. Boolean), яке вказує, чи було твердження успішним. Наприклад:

str, ok := input.(string) // no panic if input is not a string

Якщо input містить string, то str буде значенням, що лежить в основі, а ok дорівнюватиме правді. Якщо input не містить string, то str буде нульовим значенням типу string (тобто "", порожній рядок тексту), а ok дорівнюватиме неправді. Паніки не виникне в жодному разі.

Перемикачі типів

Перемикач типів може виконати кілька тверджень типу послідовно. Він має той самий синтаксис, що й твердження типу (interfaceVariable.(concreteType)), але concreteType замінено на ключове слово type. Ось приклад:

var i any = 12 // try: 12.3, true, int64(12), []int{}, map[string]int{}

switch v := i.(type) {
case int:
    fmt.Printf("the integer %d\n", v)
case string:
    fmt.Printf("the string %s\n", v)
default:
    fmt.Printf("type, %T, not handled explicitly: %#v\n", v, v)
}

Вказівки

Джен працює в сортувальному відділі великої фабрики. Сортувальний відділ має обробляти все, що до нього потрапляє, позначаючи це ярликом. Джен відповідає за речі, які наперед віднесли до чисел, і їй потрібна програма, яка допоможе з сортуванням.

Більшість примітивних значень має отримувати прості ярлики. Для чисел вона хоче, щоб рядки тексту (англ. string) мали вигляд "This is the number 2.0" (якщо число дорівнювало 2). Джен хоче однакових вихідних даних і для цілих чисел, і для чисел з плаваючою комою.

Є кілька інтерфейсів Box, які потрібно розпакувати, щоб дістатися їхнього вмісту. Для NumberBox вона хоче, щоб рядки тексту мали вигляд "This is a box containing the number 3.0" (якщо метод Number() повертає 3). Для FancyNumberBox вона хоче, щоб рядки тексту мали вигляд "This is a fancy box containing the number 4.0", але лише якщо тип є FancyNumber.

Усе несподіване має видавати "Return to sender", щоб Джен могла відіслати його назад туди, звідки воно прийшло.

1. Описати прості числа

Джен хоче, щоб числа повертали рядки тексту на кшталт "This is the number 2.0" (з однією цифрою після десяткової коми):

fmt.Println(DescribeNumber(-12.345))
// Output: This is the number -12.3

2. Описати коробку з числом

Джен хоче, щоб коробки з числами повертали рядки тексту на кшталт "This is a box containing the number 2.0" (знову ж таки з однією цифрою після десяткової коми):

fmt.Println(DescribeNumberBox(numberBoxContaining{12}))
// Output: This is a box containing the number 12.0

3. Реалізувати метод, який вилучає число з вигадливої коробки

Джен потрібна допоміжна функція, щоб вилучити число з FancyNumberBox. Якщо FancyNumberBox є FancyNumber, вилучіть його значення й перетворіть його з string на int. Будь-який інший тип FancyNumberBox має повертати 0.

fmt.Println(ExtractFancyNumber(FancyNumber{"10"}))
// Output: 10
fmt.Println(ExtractFancyNumber(AnotherFancyNumber{"4"}))
// Output: 0

4. Описати вигадливу коробку з числом

Якщо FancyNumberBox є FancyNumber, Джен хоче, щоб рядки тексту мали вигляд "This is a fancy box containing the number 4.0". Будь-який інший тип FancyNumberBox має видавати "This is a fancy box containing the number 0.0".

fmt.Println(DescribeFancyNumberBox(FancyNumber{"10"}))
// Output: This is a fancy box containing the number 10.0
fmt.Println(DescribeFancyNumberBox(AnotherFancyNumber{"4"}))
// Output: This is a fancy box containing the number 0.0

ПРИМІТКА: ми маємо використати функцію ExtractFancyNumber!

5. Реалізувати DescribeAnything, яка використовує їх усі

Це головна функція, яка потрібна Джен і яка приймає будь-які вхідні дані. DescribeAnything має делегувати іншим функціям, залежно від типу переданого значення. А саме:

  • int і float64 мають обидва делегувати DescribeNumber
  • NumberBox має делегувати DescribeNumberBox
  • FancyNumberBox має делегувати DescribeFancyNumberBox
  • будь-що інше має давати "Return to sender"
fmt.Println(DescribeAnything(numberBoxContaining{12.345}))
// Output: This is a box containing the number 12.3
fmt.Println(DescribeAnything("some string"))
// Output: Return to sender
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Go Exercism

Час розпочати Сортувальна кімната?

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