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", щоб Джен могла відіслати його назад туди, звідки воно прийшло.
Джен хоче, щоб числа повертали рядки тексту на кшталт "This is the number 2.0" (з однією цифрою після десяткової коми):
fmt.Println(DescribeNumber(-12.345))
// Output: This is the number -12.3
Джен хоче, щоб коробки з числами повертали рядки тексту на кшталт "This is a box containing the number 2.0" (знову ж таки з однією цифрою після десяткової коми):
fmt.Println(DescribeNumberBox(numberBoxContaining{12}))
// Output: This is a box containing the number 12.0
Джен потрібна допоміжна функція, щоб вилучити число з FancyNumberBox.
Якщо FancyNumberBox є FancyNumber, вилучіть його значення й перетворіть його з string на int.
Будь-який інший тип FancyNumberBox має повертати 0.
fmt.Println(ExtractFancyNumber(FancyNumber{"10"}))
// Output: 10
fmt.Println(ExtractFancyNumber(AnotherFancyNumber{"4"}))
// Output: 0
Якщо 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!
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
Зареєструйтеся на Exercism, щоб вивчати й опановувати Go, а також 34 концепції165 вправ та справжнє наставництво від людей, і все це безкоштовно.