Я пытаюсь представить упрощенную хромосому, которая состоит из N оснований, каждое из которых может быть только одним из {A, C, T, G}
.
Я хотел бы формализовать ограничения с помощью enum, но мне интересно, какой самый идиоматичный способ эмуляции enum в Go.
Ответы:
Цитирование из спецификации языка: Йота
Таким образом, ваш код может быть как
или
если вы хотите, чтобы основания были отдельным типом от int.
источник
Ord(Base)
он не ограничен,0..3
но имеет те же ограничения, что и базовый числовой тип. Это выбор языка дизайна, компромисс между безопасностью и производительностью. При каждом касанииBase
введенного значения учитывайте «безопасные» проверки с ограничением по времени выполнения . Или как определить «значение переполнения»Base
значения для арифметики и для++
и--
? И т.д.iota + 1
чтобы не начинать с 0.Ссылаясь на ответ jnml, вы можете предотвратить появление новых экземпляров базового типа, вообще не экспортируя базовый тип (то есть писать его строчными буквами). При необходимости вы можете создать экспортируемый интерфейс с методом, который возвращает базовый тип. Этот интерфейс может использоваться в функциях извне, которые имеют дело с основами, т.е.
Внутри основной пакет
a.Baser
теперь фактически похож на enum. Только внутри пакета вы можете определить новые экземпляры.источник
base
используется только как приемник метода. Если бы вашa
пакет выставлял функцию, принимающую параметр типаbase
, это стало бы опасно. Действительно, пользователь может просто вызвать его с буквальным значением 42, которое будет принимать функция,base
поскольку оно может быть преобразовано в int. Чтобы предотвратить это, сделать : . Проблема: вы больше не можете объявлять базы как константы, только переменные модуля. Но 42 никогда не будут брошены в этот тип.base
struct
type base struct{value:int}
base
Вы можете сделать это так:
С этим кодом компилятор должен проверять тип перечисления
источник
Это правда, что приведенные выше примеры использования
const
иiota
являются наиболее идиоматическими способами представления примитивных перечислений в Go. Но что, если вы ищете способ создания более полнофункционального перечисления, подобного типу, который вы видели бы на другом языке, таком как Java или Python?Очень простой способ создать объект, который начинает выглядеть и чувствовать себя как строковое перечисление в Python:
Предположим, вам также нужны некоторые служебные методы, например
Colors.List()
, иColors.Parse("red")
. И ваши цвета были более сложными и должны были быть структурой. Тогда вы можете сделать что-то вроде этого:На этом этапе, конечно, это работает, но вам может не понравиться то, как вы должны повторно определять цвета. Если в этот момент вы захотите устранить это, вы можете использовать теги в своей структуре и поразмышлять над ее настройкой, но, надеюсь, этого достаточно, чтобы охватить большинство людей.
источник
Начиная с Go 1.4,
go generate
инструмент был представлен вместе сstringer
командой, которая делает ваш enum легко отлаживаемым и печатным.источник
Уверен, у нас здесь много хороших ответов. Но я просто подумал добавить способ, которым я использовал перечисляемые типы
Это, безусловно, один из идиоматических способов, которыми мы могли бы создавать перечисляемые типы и использовать их в Go.
Редактировать:
Добавление другого способа использования констант для перечисления
источник
Вот пример, который окажется полезным, когда есть много перечислений. Он использует структуры в Голанге и опирается на объектно-ориентированные принципы, чтобы связать их вместе в аккуратный маленький пучок. Ни один из базового кода не изменится при добавлении или удалении нового перечисления. Процесс такой:
enumeration items
: EnumItem . Он имеет целочисленный и строковый тип.enumeration
как списокenumeration items
: Enumenum.Name(index int)
: возвращает имя для указанного индекса.enum.Index(name string)
: возвращает имя для указанного индекса.enum.Last()
: возвращает индекс и имя последнего перечисленияВот некоторый код:
источник