Перечисления и йота - множество советов и приемов с примерами работающего кода.
Важно. В этом руководстве вы узнаете, как использовать перечисления без йоты в первом разделе. После этого вы также узнаете о йоте и других вспомогательных инструментах. первый раздел. Итак, сначала научись ползать, потом ходить, потом бегать!
Что такое Enum? ★
Перечисление объединяет связанные константы в один тип.
Примеры перечислений:
- Часовые пояса: EST, CST…
- Размеры футболки: маленький, средний, большой
- Статусы сервера: "Неизвестно", "Работает", "Остановлен", "Возобновлен"
Зачем нужны перечисления?
- Группировка и ожидание только некоторых связанных значений
- Поделиться общим поведением
- Избегает использования недопустимых значений
- Для повышения читабельности кода и удобства сопровождения
Как можно имитировать перечисление в Go?
Например, предположим, что вы хотите создать перечисление для будних дней.
★ Во-первых: объявите новый пользовательский тип: будний день.
Weekday объединит константы перечисления под общий тип.
type Weekday int
★ Второе: объявить связанные константы для буднего дня
Присвойте им разные числовые значения, чтобы они не конфликтовали.
const ( Sunday Weekday = 0 Monday Weekday = 1 Tuesday Weekday = 2 Wednesday Weekday = 3 Thursday Weekday = 4 Friday Weekday = 5 Saturday Weekday = 6 ) fmt.Println(Sunday) // prints 0 fmt.Println(Saturday) // prints 6
Создание общего поведения для перечисления Weekday
Вы прикрепляете методы к типу, чтобы определить его поведение.
Прикрепленные методы будут неотъемлемыми частями Weekday и совместно используемыми константами Weekday.
★ Метод String ():
func (day Weekday) String() string { // declare an array of strings // ... operator counts how many // items in the array (7) names := [...]string{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} // → `day`: It's one of the // values of Weekday constants. // If the constant is Sunday, // then day is 0. // // prevent panicking in case of // `day` is out of range of Weekday if day < Sunday || day > Saturday { return "Unknown" } // return the name of a Weekday // constant from the names array // above. return names[day] }
★ Попробуем:
fmt.Printf("Which day it is? %s\n", Sunday) // Which day it is? Sunday
★ Метод выходных дней ():
func (day Weekday) Weekend() bool { switch day { case Sunday, Saturday: // If day is a weekend day return true default: // If day is not a weekend day return false } }
Соглашение: вместо IsWeekend мы просто используем Weekend.
★ Попробуем:
fmt.Printf("Is Saturday a weekend day? %t\n", Saturday.Weekend()) // Is Saturday a weekend day? true
Автоматическое создание имен
Вы можете использовать Stringer Роба Пайка для автоматического создания метода String.
# install the stringer tool
go get -u -a golang.org/x/tools/cmd/stringer
# grab the code from here
# and save it in weekday.go
# inside your $GOPATH/src/enums
# then, run stringer to create
# enum names automatically
stringer -type Weekday weekdays.go
Автоматизировать значения перечисления с помощью: iota
→ Числовой универсальный счетчик, начиная с 0
→ Used o
только сconstant
объявлениями
→ Можно затенять. Пожалуйста, не делай этого.
Как пользоваться йотой?
Выражение йоты повторяется другими константами до тех пор, пока не появится другое присваивание или объявление типа.
Посмотрим, как йота тикает
йота увеличивается на 1 после каждой строки, кроме пустых строк и строк комментариев.
Когда не использовать йоту
const ( RestartMarkerReply = 110 ServiceReadyInNMinutes = 120 CommandOK = 200 CommandNotImplemented = 202 // ... )
Не используйте йоту для списка предопределенных значений, таких как коды состояния FTP-сервера.
const ( Fatal = iota )
Просто присвойте 0 там. Это безвредно, но и в этом нет необходимости.
Этот раздел расширит ваше понимание йоты.
Базовое выражение
type Timezone int const ( // iota: 0, EST: -5 EST Timezone = -(5 + iota) // iota: 1, CST: -6 CST // iota: 2, MST: -7 MST // iota: 3, MST: -8 PST )
Сброс йоты
// iota reset: it will be 0. const ( Zero = iota // Zero = 0 One // One = 1 ) // iota reset: will be 0 again const ( Two = iota // Two = 0 ) // iota: reset const Three = iota // Three = 0
Пропуск некоторых значений
type Timezone int const ( // iota: 0, EST: -5 EST Timezone = -(5 + iota) // _ is the blank identifier // iota: 1 _ // iota: 2, MST: -7 MST // iota: 3, MST: -8 PST )
О поведении йоты в комментариях и пустых строках
type Timezone int const ( // iota: 0, EST: -5 EST Timezone = -(5 + iota) // On a comment or an empty // line, iota will not // increase // iota: 1, CST: -6 CST // iota: 2, MST: -7 MST // iota: 3, MST: -8 PST )
Использование йоты посередине
const ( One = 1 Two = 2 // Three = 2 + 1 => 3 // iota in the middle Three = iota + 1 // Four = 3 + 1 => 4 Four )
Несколько йот в одной строке
const ( // Active = 0, Moving = 0, // Running = 0 Active, Moving, Running = iota, iota, iota // Passive = 1, Stopped = 1, // Stale = 1 Passive, Stopped, Stale )
В этой же строке все константы получат одинаковые значения йоты.
const ( // Active = 0, Running = 100 Active, Running = iota, iota + 100 // Passive = 1, Stopped = 101 Passive, Stopped // You can't declare like this. // The last expression will be // repeated CantDeclare // But, you can reset // the last expression Reset = iota // You can use any other // expression even without iota AnyOther = 10 )
Повторение и удаление выражений
const ( // iota: 0, One: 1 (type: int64) One int64 = iota + 1 // iota: 1, Two: 2 (type: int64) // Two will be declared as if: // Two int64 = iota + 1 Two // iota: 2, Four: 4 (type: int32) Four int32 = iota + 2 // iota: 3, Five: 5 (type: int32) // Five will be declared as if: // Five int32 = iota + 2 Five // (type: int) Six = 6 // (type: int) // Seven will be declared as if: // Seven = 6 Seven )
Будет повторено последнее использованное выражение и тип.
Эвены и форы
type Even bool const ( // 0 % 2 == 0 ==> Even(true) a = Even(iota % 2 == 0) // 1 % 2 == 0 ==> Even(false) b // 2 % 2 == 0 ==> Even(true) c // 3 % 2 == 0 ==> Even(false) d )
Обратный отсчет
const ( max = 10 ) const ( a = (max - iota) // 10 b // 9 c // 8 )
Сканер текста Go stdlib также использует этот шаблон.
Производство алфавитов
const ( // string will convert the // expression into string. // // or, it'll assign character // codes. a = string(iota + 'a') // a b // b c // c d // d e // e )
Побитовые операции
type Month int const ( // 1 << 0 ==> 1 January Month = 1 << iota February // 1 << 1 ==> 2 March // 1 << 2 ==> 4 April // 1 << 3 ==> 8 May // 1 << 4 ==> 16 June // ... July August September October November December // Break the iota chain here. // AllMonths will have only // the assigned month values, // not the iota's. AllMonths = January | February | March | April | May | June | July | August | September | October | November | December )
При степени двойки этот код создает всеобъемлющую константу из предыдущих констант.
Остерегайтесь нулевого значения
type Activity int const ( Sleeping = iota Walking Running ) func main() { var activity Activity // activity initialized to // its zero-value of int // which is Sleeping }
0 - это нулевое значение для целых чисел. Таким образом, вы не можете знать, инициализировано действие или нет; Он действительно в спящем состоянии?
йота + 1 трюк
const ( Sleeping = iota + 1 Walking Running ) func main() { var activity Activity // activity will be zero, // so it's not initialized activity = Sleeping // now you know that it's been // initialized }
Используйте «iota + 1», чтобы убедиться, что тип перечисления инициализирован.
Неизвестный шаблон состояния
const ( Unknown = iota Sleeping Walking Running )
Начните с «Неизвестно», чтобы быть уверенным в инициализации перечисления.
▶ ︎ В греческом алфавите йота - девятая и самая маленькая буква (с точки зрения ее визуального представления). Произносится как это. Он представляет собой очень небольшое количество чего-то.
⟦В векторной математике и в некоторых языках программирования он использовался для создания массива последовательных целых чисел, например 1, 2, 3, 4…⟧
♛ Если вам, как и мне, интересно, вы можете прочитать реализацию констант и йоту в исходном коде Go. Йота объявлена здесь как const iota = 0
. И постоянная реализация находится здесь, а поведение увеличения йоты - здесь.
★ Йота фигурирует в книге Айверсона: Язык программирования (APL) 1962 года.
★ Йота позаимствована у APL одним из создателей Go, Кеном Томпсоном.
★ Обсуждение того, как заставить iota работать с переменными в Go 2.
Хорошо, на этом пока все. Спасибо, что дочитали до сих пор.
Давайте оставаться на связи:
- 📩 Присоединяйтесь к моей рассылке новостей
- 🐦 Следуй за мной в твиттере
- 📦 Получите репозиторий Go для бесплатных руководств, примеров и упражнений
- 📺 Учитесь Go с моим курсом Go Bootcamp
- ❤️ Хотите помочь? Пожалуйста, аплодируйте и поделитесь статьей. Пусть другие люди тоже узнают из этой статьи.