Comments 36
Мне кажется, Go компилятор мог спокойно создавать её за меня и позволить писать thing.TimePtr = &time.Now().
Мог бы, наверное. Но там принцип:
Programs using times should typically store and pass them as values, not pointers. That is, time variables and struct fields should be of type time.Time, not *time.Time.
Недавно в целях изучения языка решил написать свой MitM-proxy на Go. В сравнении с Python 3.* — некоторые вещи на текущий момент выглядят некрасиво, к примеру нельзя сделать slice с отрицательным значением "arr[:-10]", регулярные выражения, которые не могут быть константами и благодаря "магии" внутри Go не перекомпилируются каждый раз (но для того, чтобы об этом узнать — нужно читать документацию), а также другие досадные мелочи, но есть масса преимуществ.
Во-первых — он ОЧЕНЬ быстрый (если сравнивать со стандартными библиотеками Python)!
Во-вторых — первое окружение которое очень просто настраивается (да-да — это камень в сторону venv/node_modules).
Из инструментов для комфортной работы/отладки с ним — было достаточно atom и плагина go-plus.
Во-вторых — первое окружение которое очень просто настраивается (да-да — это камень в сторону venv/node_modules).
Что может быть удобнее, чем virtulaenvwrapper + .venv файлик?
Подход go в духе, когда "будем хранить все зависимости в репе" может с практической точки зрения и простой, но в результате это выглядит хуже некуда и попытки настроить себе базовый проект у меня с первого раза превратились в страдания. Потому что переменные окружения, которые надо прописывать, а еще и нет единого стандарта пакетов.
ИМХО: В случае с Go — хранить зависимости в репе можно, т.к. на размер и скорость работы с проектом это влияет не существенно. А при наличии go dep в базовых утилитах к языку — придется решить и проблему стандарта пакетов и проблему с необходимостью отслеживать версии зависимых пакетов вручную. Думаю что будет здорово, если при использовании git, вместо загрузки зависимого пакета будет создаватся submodule с необходимой версией.
А если есть необходимость использовать различные ENV-спецефические окружения, то удобнее — docker/lxc…
регулярные выражения… благодаря «магии» внутри Go не перекомпилируются каждый разА точно Go не перекомпилирует? Вот честно не могу найти такого в документации, наверное плохо ищу?
С другой стороны Python как раз таки имеет кеш для регулярок.
P.S.: А у стандартной библиотеки Go — очень подробные комментарии :)
Я подумал, что Вы про методы вроде `regexp.MatchString(pattern, str)`. Аналогичные методы в Python как раз имеют кеш, а вот в Go каждый раз идет полный парсинг регулярки.
PS: Судя по всему `regexpRO` имеет место быть только для упрощения реализации Copy() (все константные поля копируются легким движением руки). Ну может еще кто-то находит такой вариант более читабельным.
всё чувствуется как железобетонно надежное… Моё внутреннее чутье показывает, что это частично из-за того, что в Go нет исключенийНу ок, допустим. Но потом
я также использовал вызовы panic() для таких вещей как вызовы к базе данных, которые «должны всегда работать»Хм…
на самом верхнем уровне, я ловил эти паники с помощью recover() и корректно логировал их и даже добавил немного кода, чтобы отправлять стектрейс мне на почтуА, ну так конечно получается железобетонно. Не то что с исключениями.
Кстати, об err != nil… даёт очень хорошее чувство «это реально надёжно, я корректно обрабатываю каждую ошибку»Совершенно непонятно, какие такие «каждые» ошибки обрабатывает автор.
1. Код возврата: тут что-то случилось, но, в принципе, ничего страшного, если нужно — можешь продолжать работу.
2. panic: всё — наш модуль «кончился» работу с ним продолжать невозможно, но если в программе есть другие модули — они могут ещё кому-то послужить.
В случае же с исключениями задача подобного «разделения обязанностей» возможена на программиста, который модулем пользуется — а он, зачастую, не знает толком: можно ли модуль как-то «спасти» или он безвозвратно испорчен.
Теоритически схема с исключениями более гибкая, на практике — это скорее мешает, чем помогает…
Все те ошибки при которых можно продолжить работу.А кто определяет, можно ли после ошибки проолжить работу или нет? Вызывающая сторона или вызываемая?
В случае же с исключениями задача подобного «разделения обязанностей» возможена на программиста, который модулем пользуется — а он, зачастую, не знает толком: можно ли модуль как-то «спасти» или он безвозвратно испорчен.
Модуль то как раз «безнадежно испорчен», а вот код, который его вызвал — еще «можно спасти», но об этом может знать только вызывающий программист.
Ну вот к примеру, я формирую результаты боя в игре, для каждого юзера вызываю функцию `getStat(user)` из другого модуля, ее результат для меня не смертельно важен — если для каких-то юзеров она упала, я просто выведу знаки вопроса вместо циферок. И вот на Джаве — просто словил ексепшн и вывел вопросы. А программист на Го ведь самый умный, у него упал запрос к базе, который обычно не падает и он решает запаниковать. И вот весь расчет коту под хвост.
А потому-что в Джаве хорошее, продуманное решение, а в Гоу — очередной мусор для хипстеров.
И, очевидно, человек это придумал из-за крайне кривой и неудобной работы с ошибками в Гоу
google.github.io/styleguide/cppguide.html#Exceptions
llvm.org/docs/CodingStandards.html#do-not-use-rtti-or-exceptions
On their face, the benefits of using exceptions outweigh the costs, especially in new projects. However, for existing code… problematic to integrate the new project into existing exception-free code...Т.е. вообще сами по себе исключения в С++ дают пользы больше, чем вреда, и их бы использовали… Но в одной конкретной корпорации есть куча легаси C++ кода, который с исключениями совсем не дружит.
In an effort to reduce code and executable size, LLVM does not use RTTI (e.g. dynamic_cast<>;) or exceptionsТ.е. из-за размеров бинарников не используют RTTI и исключения… Ну это разумеется применимо и к статически линкуемому Go, напичканому данамическими кастами (привет interface{}). Походу именно из-за отсутствия исключений бинарники у Go получаются такими миниатюрными, а я то все голову ломал.
PS: искренне прошу, не надо приводить бессодержательные доводы аля «ну для C++ преимущества исключений перевешивают конечно, но вот для Go нет! он ведь совсем другой, не такой как все!». Уж коли приводите ссылки для С++, то давайте в этих рамках и вести обсуждение.
Непонятно, с чем вы сейчас воюеете. Спорность пользы от исключений это такая заезженная и банальная тема, что отрицать её совсем глупо. Сотни статей написаны про то, почему исключения это зло, а соотношение "польза/вред" это довольно субъективная штука, которая, безусловно зависит от реализации и языка, о котором речь.
Хорошо или плохо что в Go исключения таки есть (паника), но их не принято использовать — это отдельная тема. Хорошо или плохо, что и в других языках можно пользовать кодами возврата (например возвращать Either<> в Java), но их используют куда меньше чем исключения — тоже отдельная тема.
Но когда кто-то приводит ссылку для «аргументации через авторитет» (уже само по себе не очень), но в которой еще явно белым по черному написано «в целом исключения годнота»… Ну, меня коробит.
Уж коли написано сотни статей — вот их и приводите (если они конечно адекватные) :)
Ну тогда и я повоюю с искажением фактов: комментарий serge-phi не был "аргументацией через авторитет" — ссылка была приведена для подтверждения посыла "польза исключений — спорная тема": в ссылке хорошо описаны и плюсы и минусы, что, как бы, подтверждает поинт.
И, кстати, "утверждение через авторитет" не является логической ошибкой — если "авторитет" действительно авторитет и обладает гораздо более весомым мнением, то это может быть вполне себе мощный аргумент.
Ну и да, называть паники "в Go тоже есть исключения" это как говорить "в самолете тоже есть колёса, но их не принято использовать" (подразумевая шасси). Круглая форма и похожая функция не означает, что это одно и то же.
ссылка была приведена для подтверждения посыла «пользя исключений спорная тема»Простите, но надо быть совсем недалеким, что бы не понимать что у любой идеи/техрешения есть и сильные и слабые стороны :)
Я тоже вот например совсем не согласен, что Go мусор из-за ситуации с обработкой ошибок… Он мусор, но по иным причинам :)
Еще раз — приводите правильные ссылки и вопросов не будет (или будут, но другие). Вы сами только что сказали что их прямо «сотни», т.е. минимум 200. Думаю есть из чего выбрать :)
И, кстати, «утверждение через авторитет» не является логической ошибкой — если «авторитет» действительно авторитет и обладает гораздо более весомым мнением, то это может быть вполне себе мощный аргумент.Ну право, одно дело когда вы обратились к авторитету а он вам «ну в твоем случае я проанализировал все… надо делать такто и такто». Но нет ведь, мы просто смотрим со стороны что наш мастер-авторитет делает. Большую часть времени не понимаем почему мастер прянял то или иное решение, он ведь нам не отчитывается и ведет большую часть работы закрыто… А потом пытаемся повторить :)
Он мусор, но по иным причинам :)
Я думаю, что называть мусором другие языки программирования, которые оказались гораздо более удачно реализованными и более популярными, чем ваш любимый язык, не делает чести вам ни как собеседнику, ни как представителю Clojure-коммьюнити. На оскорблениях хорошее коммьюнити не построишь.
Еще раз — приводите правильные ссылки и вопросов не будет
Ссылка вполне себе "правильная" — она кратко и наглядно демонстрирует и перечисляет плюсы и минусы.
Большую часть времени не понимаем почему мастер прянял то или иное решение,
Согласен.
На оскорблениях хорошее коммьюнити не построишь.Ой какая грубая уловка в риторике попытаться противопоставить собеседника сообществу, не надо так ;)
Про мусор — это мое личное мнение. И совершенно никаим боком ни к Clojure, ни к иному языку, ни к какому либо коммьюнити не относится :)
Своим определением («мусор») я не пытаюсь никого оскоробить или принизить язык. Он во многих местах сделан клево, я его прямо щас использую. И он очень даже к месту ;)
Но в целом я считаю этот язык очень сильно переоценненым, во многом благодаря авторитету его создателей и компании, где он зародился… В целом как «опенсорсный язык, применимый для разных компаний и проектов» он для меня «мусор».
Ссылка вполне себе «правильная» — она кратко и наглядно демонстрирует и перечисляет плюсы и минусы.Для С++. Плюсы и минусы там отнюдь не универсальные.
А Go, как известно, отнюдь не C++.
Плюсы и минусы там отнюдь не универсальные.
Автор комментария не утверждал, что они универсальные, он утверждал, что тема спорная, а не однозначная.
А Go, как известно, отнюдь не C++.
Хех, вы несколько комментариев выше сами такую аргументацию высмеивали("PS: искренне прошу, не надо приводить бессодержательные доводы аля «ну для C++ преимущества исключений перевешивают конечно, но вот для Go нет! он ведь совсем другой, не такой как все!»")
Kолёса у самолётов (не у всех, впрочем) всё-таки есть, а шасси — это слегка другое. (:
Мне тоже кажется, что языки, которые постулируют "отказ от исключений" не совсем честны в этом плане.
что было глотком свежего воздухе после битвы на мечах от 20 секунд инкрементальной и 20 минут полной компиляции в Scala.
Автор явно утрирует и набрасывает. Если речь идет о таком небольшом проекте, то компиляция в Scala тоже будет занимать секунды. Не знаю о каких 20 минутах с нуля и 20 секундах инкрементальной он говорит, когда лично у меня, полная перекомпиляция проекта в ~20kloc с обильным использованием имплиситов, макросов и вот этого всего + то же ранее упомянутое, переформатирование всех сорцев — занимает ~50 с. на обычном домашнем ноуте (scala 2.12.4 и sbt 1.0.3).
Изучение Go путём портирования небольшого Python веб-бекенда