Я пытаюсь выполнить упражнение №1.4 "Язык программирования Go", которое требует от меня набора. Я могу создать наборный тип, но почему в языке нет его? go, пришедший из Google, где также возникла гуава, почему разработчики языка не решили добавить поддержку фундаментальных структур данных? зачем заставлять пользователей создавать свои собственные реализации для чего-то столь простого, как набор?
data-structures
go
set
anjanb
источник
источник
Ответы:
Отчасти потому, что в Go нет универсальных шаблонов (поэтому вам понадобится один набор-тип для каждого типа или прибегать к отражению, что довольно неэффективно).
Отчасти потому, что если все, что вам нужно, это «добавить / удалить отдельные элементы в набор» и «относительно компактно», вы можете получить немного этого, просто используя
map[yourtype]bool
(и устанавливая значениеtrue
для любого элемента в наборе ) или, для большей экономии места, вы можете использовать пустую структуру в качестве значения и использовать_, present = the_setoid[key]
для проверки наличия.источник
map[T]struct{}
вместоmap[T]bool
.Одна из причин заключается в том, что создать набор из карты легко:
союз
пересечение
Реализовать все остальные операции над наборами не так уж и сложно.
источник
false
) правильно скажет об этом. Не нужна идиома-запятая для тестирования.map[int]struct{}
вместоbool
, потому что пустая структура занимает в памяти 0 байтов. Я недавно написал суть этого gist.github.com/bgadrian/cb8b9344d9c66571ef331a14eb7a2e80Как писал Ватин: поскольку в go отсутствуют универсальные шаблоны, он должен быть частью языка, а не стандартной библиотекой. Для этого вам придется засорять язык набором ключевых слов, объединением, пересечением, различием, подмножеством ...
Другая причина в том, что совсем не ясно, какова «правильная» реализация набора:
Есть функциональный подход:
Это набор всех четных int. Он имеет очень эффективный поиск и объединение, пересечение, различие и подмножество, которые можно легко выполнить с помощью функциональной композиции.
У карты нет такой проблемы, поскольку вы храните что-то, связанное со значением.
источник
+
для объединения,-
для разности,*
для пересечения,<=
для подмножества,>=
для надмножества,=
для равенства,<>
для неравенства иin
для членства. Таким образом, в Go это будет только одно новое ключевое слово -in
. С другой стороны, встроенные наборы Паскаля работают только с «порядковыми числами», то есть с любым типом, в основе которого лежит представление целочисленного значения некоторого размера.s[key]
(как если быs
был amap[T]bool
) вместоkey in s
.n % 2 == 0
?Другая возможность - использовать наборы битов, для которых существует хотя бы один пакет, или вы можете использовать встроенный большой пакет. В этом случае в основном вам нужно определить способ преобразования вашего объекта в индекс.
источник