Pull to refresh
3
0
Send message
В Go нет шаблонов. Ряд контейнеров встроен в язык (вектор и map), но всем не хватает шаблонов. Так как очень часто требуется несколько разных типов, но с одинаковыми обработчиками. И многое другое.
Хорошо, а как вы оцениваете выразительные фичи Перла? Например, всем известная программа: $??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see
Очень выразительно, не правда ли?

Разработчики Go, я так понимаю, пошли иным путем. Если тебе нужно сделать парсер, то воспользуйся специальным инструментом, например, flex/bison.
Когда компилируется большой проект, компилятор может сотни (или тысячи) раз компилировать один и тот же заголовочный файл. А если этот файл содержит в себе сложные шаблонные конструкции? Тут спасает только прекомпиляция заголовков, когда компилятор один раз компилирует все часто используемые большие заголовочные файлы, а потом просто использует полученный код при компиляции исходников.
Чем вам шаблоны не угодили? Шаблоны это мощнейшая фича С++, которая позволяла делать на нем то, что язык изначально не поддерживал (STL, например).
Подозреваю, что не видно, так как не нужно.
Кто сказал, что аналог должен обладать той же скоростью работы? Он должен выполнять ту же функцию.
Просто в Go программа получается легко читаемой. Берешь кусок кода и почти сразу понятно, что он делает. На том же С++ это совсем не обязательно (например, если взять кусок кода с декларацией парсера через boost::spirit, особенно, если для сокращения писанины активно использовался using).
Для С возможно. Для С++ другого пути нет, ИМХО. Так как С++ очень сложный язык, компиляция программы, которая активно использует шаблоны (тот же буст), это вообще тушите свечи — компилятор зашивается из-за объемов разворачиваемых шаблонов. Одно спасение — прекомпилированные заголовки. Но блин, как-то это все криво. Вообще, заголовочные файлы (как и препроцессор) это страшный анахронизм Си, не в последнюю очередь из-за которого страдает развитие С++.
Тут речь в первую очередь про экспорт шаблоных функций. Что вообще изначально было криво. А то что C++ ABI не совместим у разных компиляторов известно очень давно.
Основная масса API — имеет интерфейс С. И вот его обернуть во все, что угодно, проблем нет.
А что с Go? Там просто многие привычные подходы поставлены с ног на голову. Все на С++ привыкли, что берем библиотеку, наследуемся от базового класса и юзаем производный. В Го все иначе. Библиотеки объявляют необходимый им интерфейс, а ты в программе уже пишешь класс (структуру), которая соответствует этому (возможно, не только этому) интерфейсу.
Да, в Go не хватает дженериков. Из-за этого ряд задач решается неэффективно или муторно.
Легко. У Go есть интерфейсы и рефлексия. sync.Map же как-то написали. Другое дело, что по сравнению с дженериками он сильно проиграет по скорости работы и выразительности использования (дженериков реально в Go не хватает). Но поставленную задачу на нем сделать можно.
Про eDSL ничего не скажу. Я бегло посмотрел что это, разбираться не стал. Скорее всего, это на Go сделать нельзя. А вот задачу, которую решают с помощью eDSL решить на Go можно. Другое дело, может быть это будет не так эффективно или не так выразительно.
Так они уже с 11-й версии устарели. Вот в 17-й их и выпилили. Давно пора использовать std::bind.
Вы видимо меня не совсем верно поняли. Когда подключаете заголовочный файл от старого проекта, то этот заголовочный файл интерпретируется как не соответствующий новому стандарту. Как вариант, можно реализовать через модуль (юнит). Т.е. старый кусок кода собирается в модуль, экспортирующий интерфейс в современном виде. Накладных расходов в рантайме я не вижу. А уж про ABI так вообще молчу. Причем тут двоичная совместимость? Речь идет про фронт компилятора, а бэк можно и старый оставить.
Никто не мешает сделать эту совместимость частичной. указываешь номер стандарта в первой строчке исходника и все. Если не указан, то считается последний стандарт с поддержкой си.
Эх. Жаль, что логическая репликация не работает с фрагментированными таблицами, а создавать подписку и подписчика для каждого фрагмента муторно.
Это уже давно сделали.
А зачем считывать все при перемещении в конец? Если речь про обычный файл, то делаем lseek на -n байт от конца и парсим строки. Если недостаточно — еще откатываемся назад. Это сложнее, конечно, но быстрее работает. Меня в less это убивает — очень долго в конец переходит…
Понимаю, код не красивый — сам такие конструкции стараюсь избегать. Но зато смысл работы очевидный, в отличие от первого варианта.
Если честно, я вообще не вижу смысла в вашем коде. Так как вторая проверка статуса имеет смысл только внутри первой.
А причем тут вообще while (cond) {… break; }?
Лучше замени на функцию с return. Это более красивое решение.
С goto могут возникнуть проблемы с созданием переменных. Имхо, лучше выделить в отдельную функцию.
Однопроходовый цикл while используется вместо кучи if () goto… Согласен, не совсем красивый код, но всяко лучше кучи goto.
Зря отказались от методов в пользу обычных функций. Большинство компиляторов оптимизируют их по разному. В частности, указатель this хранится и передается в отдельном регистре, который у обычных функций для этих целей не используется. В обычной жизни разницу не заметить, конечно, но высоко нагруженные и имеющие множественые вызовы методов одного класса программы будут иметь заметную разницу в скорости.

Information

Rating
Does not participate
Registered
Activity