Отказ от ответственности: я играл в Go всего один день, так что есть хороший шанс, что я многое пропустил.
Кто-нибудь знает, почему в Go нет реальной поддержки generics / templates / whatsInAName? Итак, есть общий map
, но он предоставляется компилятором, а программист на Go не может написать свою собственную реализацию. Учитывая все разговоры о том, чтобы сделать Go как можно более ортогональным, почему я могу ИСПОЛЬЗОВАТЬ общий тип, но не СОЗДАТЬ новый?
Особенно, когда дело доходит до функционального программирования, есть лямбды, даже замыкания, но с системой статических типов, не имеющей обобщений, как мне написать, ну, общие функции более высокого порядка, такие как filter(predicate, list)
? Хорошо, связанные списки и тому подобное можно делать, interface{}
жертвуя безопасностью типов.
Поскольку быстрый поиск в SO / Google не дал никакой информации, похоже, что дженерики, если они вообще будут добавлены в Go, будут запоздалыми. Я верю, что Томпсон справится лучше, чем ребята из Java, но зачем убирать дженерики? Или они запланированы и просто еще не реализованы?
interface{}
жертвует безопасностью статического типа. Однако это несколько странная жалоба, когда упоминается Scheme в следующем абзаце, поскольку Scheme обычно не имеет проверки статического типа.Ответы:
этот ответ вы найдете здесь: http://golang.org/doc/faq#generics
источник
interface{}
как самый основной тип интерфейса, и каждый объект предоставляет его. Если вы сделаете контейнер, содержащий их, он может принять любой (не примитивный) объект. Так что это очень похоже на контейнер для храненияObjects
в Java.Перейти 2
На https://blog.golang.org/go2draft есть эскизный проект для дженериков .
Перейти 1
Расс Кокс, один из ветеранов го, написал сообщение в блоге под названием «Общая дилемма» , в котором он спрашивает:
Медленные программисты являются результатом отсутствия дженериков, медленные компиляторы вызваны С ++, подобными дженерикам, а медленное время выполнения проистекает из подхода упаковки-распаковки, который использует Java.
Четвертая возможность, не упомянутая в блоге, идет по пути C #. Генерация специализированного кода, как в C ++, но во время выполнения, когда это необходимо. Мне это очень нравится, но Go очень не похож на C #, так что, вероятно, это вообще не применимо ...
Я должен упомянуть, что использование популярной техники универсального программирования, подобной Java 1.4, в go, которая приводит к
interface{}
возникновению тех же проблем, что и упаковка-распаковка (потому что это то, что мы делаем), помимо потери безопасности типов во время компиляции. Для небольших типов (например, целых чисел) Go оптимизируетinterface{}
тип таким образом, чтобы список целых чисел, приведенных к интерфейсу {}, занимал непрерывную область памяти и занимал в два раза больше места, чем обычные целые числа. Тем не менее, существуют накладные расходы на проверки времени выполнения при приведении изinterface{}
. Ссылка .Все проекты, которые добавляют универсальную поддержку (их несколько, и все они интересны), единообразно идут по маршруту C ++ генерации кода времени компиляции.
источник
[]interface{}
используют вдвое больше ОЗУ, чем[]int
. Хотя это правда, даже меньшие типы (т. Е. Байтовые) используют до 16 раз больше ОЗУ, чем[]byte
.Несмотря на то, что универсальные шаблоны в настоящее время не встроены, существует несколько внешних реализаций универсальных шаблонов, которые используют комментарии в сочетании с небольшими утилитами, генерирующими код.
Вот одна из таких реализаций: http://clipperhouse.github.io/gen/
источник
Собственно, согласно этому сообщению:
источник
Параметрический полиморфизм (дженерики) находится на рассмотрении для Go 2 .
Этот подход представит концепцию контракта , который можно использовать для выражения ограничений на параметры типа:
Такой контракт затем можно было бы использовать следующим образом:
Это предложение на данном этапе.
Ваша
filter(predicate, list)
функция может быть реализована с таким параметром типа:В этом случае ограничений нет
T
.источник