Хотите выучить новый язык программирования? Рассмотрите Go (Golang)

Хотите выучить новый язык программирования? Рассмотрите Go (Golang)

Быстрое выполнение, эффективная многопоточность и упрощенный, легкий в освоении синтаксис – одни из самых привлекательных функций.

Когда я впервые начал изучать Go, я начал работать над личным проектом, который заставил бы меня освоить новый синтаксис (я всегда придумываю проект, когда изучаю новый язык).

Я решил, что создам приложение командной строки, которое перечисляет субдомены, чтобы помочь с обнаружением активов для программ вознаграждения за ошибки. Поэтому ему приходилось выполнять несколько HTTP-запросов параллельно, как в gobuster, но я хотел заново изобрести это колесо с некоторыми дополнительными функциями, такими как очистка HTML-ответов для получения интересной информации, связанной с безопасностью.

Это была проблема, которую я хотел решить, используя Go-рутины. Было бы сложно, учитывая неизвестное количество HTTP-запросов, поэтому потребовалось бы научиться эффективно их обрабатывать.

Первые впечатления

Сразу же я обнаружил, что синтаксис был мне знаком, хотя раньше я не читал документацию. Концепции казались мне интуитивными (другие могут не согласиться). Использование defer сразу обрело смысл. Пакет fmt для форматирования строк, казалось, решил проблему, о которой я не знал. Я начал понимать намерения разработки Go как еще одного языка программирования. Поэтому я решил углубиться в первоначальную цель Go, чтобы определить, стоит ли изучать этот язык.

Почему Go был разработан

Цель

Go был разработан Google, чтобы сделать многопроцессорную разработку более эффективной и безопасной, чтобы улучшить обслуживание, надежность и валидность серверного программного обеспечения с течением времени. Для Google это было ответом на проблемы, с которыми они столкнулись в связи с мучительно долгим временем компиляции и проблемами, связанными с обработкой крупномасштабных данных, что является сегодня одним из их наиболее распространенных применений в производстве. Они хотели язык, который фокусируется на масштабируемости, удобочитаемости и многопоточности. Он родился от разочарования в других языках. Они взяли наиболее желательные концепции из существующих языков и попытались улучшить и объединить их, чтобы сформировать Go. Например, пакет fmt, эффективная библиотека для обработки строк:

Пакет fmt реализует отформатированный ввод/вывод с функциями, аналогичными printf и scanf в C. Формат «verbs» взят из C, но проще.

Это пример использования функций из успешного и популярного языка, в данном случае C, и его улучшения.

Многопоточность Go была смоделирована CSP; с использованием каналов, избегая синхронизации общих данных. Они думали, что это будет более простой и безопасный способ общения.

Особое внимание было уделено простоте. Потребовался продуманный стиль кода, сформированный сообществом Go, с признанным стилем go. Тот, который поддерживается в разных проектах, что сократит время, затрачиваемое на настройку правил линтинга и изучение различных подходов к стилю кода во время разработки, что является важным фактором при работе в команде.

Это теоретически уменьшило бы разницу между разработчиками, когда речь заходит о стилях и подходах к коду, таких как JavaScript (многие многие правила Eslint).

Подход

Используемый подход сочетал в себе простоту программирования на интерпретируемом динамически типизированном языке с эффективностью и безопасностью статически типизированного компилируемого языка. Он имеет примитивные типы, такие как int, byte и string со встроенными картами. Имеются указатели. Принцип ортогональности был важен при разработке Go и является основой для функционального подхода.

Go использует структуры для представления данных и пользовательские интерфейсы для представления абстракции. Пользователи продолжают спорить о том, является ли Go объектно-ориентированным. Если вы Java-разработчик, вам будет трудно сначала увидеть объектно-ориентированную сторону аргумента. Попытка увидеть объектную ориентацию в Go может быть вызвана тем, что вы ищете иерархию типов, тогда как в Go нет иерархии типов. Существуют структуры, которые вы не можете наследовать, но соответствуют стилю объекта. Go просто предпочитает композицию наследованию. Вы можете достичь полиморфизма через принятие интерфейсов. Интерфейс принимается любым типом объекта, который удовлетворяет этому интерфейсу.

В дополнение к этим основным концепциям Go осознал необходимость многопоточности благодаря многоядерной обработке. Многопоточность пришла в форме go-рутин и каналов. В большой многопоточной программе автоматическая сборка мусора также важна как эффективное управление памятью. Модульное тестирование было сделано так же просто, как использование префикса _test.go, объявленного в том же каталоге, что и исходный файл.

Зачем мне это учить?

Многопоточность

В Go многопоточность сильно укорена. Go-рутины – это дешевые, легкие нити исполнения. Невероятно легко реализовать многопоточность в Go. Использование ключевого слова go порождает новый поток, который совместно используется несколькими ядрами в наборе потоков. Запрограммированные значения занимают всего несколько килобайт и обрабатываются средой выполнения Go, которая перемещает подпрограммы go в различные выполняемые потоки, чтобы избежать блокировки. Это делает выполнение асинхронным и быстрым; почти так же быстро, как C/C ++. Вы можете контролировать количество подпрограмм с помощью каналов, которые, несмотря на синхронность, являются асинхронными.

Среда выполнения Go использует изменяемые, ограниченные стеки, которые уменьшают стеки. Среда выполнения изменяет размер памяти для автоматического сохранения стека. Сотни тысяч программ могут работать в одном и том же адресном пространстве.

Простота

Язык go был разработан с минималистским подходом. Там нет классов или наследства. Эти функции, которые являются частью популярных языков, таких как Java и Python, заменены структурами. Go строго и статически типизирован. Использование интерфейсов приветствуется. Статическая типизация предназначена для уменьшения ошибок во время компиляции. Это также облегчает обучение.

В то время как в других языках, таких как JavaScript, вы разрываетесь между многовариантными подходами, парадигмами и соглашениями, в Go есть один подход, который повсеместно принят в качестве руководства. Это облегчает анализ вашего кода в команде и делает интеграцию более гладкой.

Несмотря на то, что нет неявных преобразований, но синтаксические издержки все еще удивительно малы. Он производит более читаемый, менее сложный код.

Быстрота

Компилятор статически связан. Это приводит к двоичному исполняемому файлу посредством компиляции, не имея дело с внешними зависимостями. Исполняемый двоичный файл, который был скомпилирован в собственном машинном коде без использования виртуальной машины, делает его более быстрым и переносимым, несмотря на увеличение размера.

Кроме того, другие области Go также стремительны. Например, время компиляции, как было упомянуто, и время для производства. В Go основное внимание уделяется производительности труда разработчиков, что в первую очередь обусловлено ее простотой. Это ускоряет переход от первоначальной концепции/идеи к производству.

Что с Go не так?

Нет дженериков

Это спорный вопрос. Использование дженериков в таких языках, как Java, улучшает возможность повторного использования кода, обеспечивая при этом безопасность типов. Сообщество go подняло эту «проблему», и она была рассмотрена. Тем не менее, их текущая позиция заключается в том, что преимущества дженериков не перевешивают преимущества простоты и удобочитаемости (без дженериков).

Условия гонок

«Не общайтесь, разделяя память; вместо этого делитесь памятью, общаясь»

Преимущества, которые приносит эта мантра, также делают Gо восприимчивым к условиям гонки.

Из-за изменчивости структур Go (и отсутствия неизменяемых структур данных) вы вынуждены обмениваться изменяемыми данными между несколькими многопоточными процессами. Примером этого является отправка указателя вниз по каналу без глубокой копии, а внутренне изменяемая природа открывает дверь к условиям гонки. Каналы могут улучшить многопоточное программирование, но существует реальный риск состояния гонки, при котором каналы ничего не делают для предотвращения.

В Go CLI встроен детектор гонки, чтобы помочь определить условия гонки.

Проверка ошибок

Проверка на ошибки очень явная. Там нет попытки… поймать заявления. Вы должны изменить свой подход и мышление, когда дело доходит до обработки ошибок. Особенно, если вы привыкли к другим языкам. Они считают, что отсутствие исключений предотвращает запутанный код и перегрузку возвращаемого значения. Это связано с его потребностью в простоте. Вы можете обработать исключения с panic и recover, однако, в действительно исключительных обстоятельствах. Существует также канонический тип интерфейса ошибки, который Быстрое выполнение, эффективная многопоточность и упрощенный, легкий в освоении синтаксис – одни из самых привлекательных функций. строку ошибки с помощью Error().

Разработчики Go подходят к ошибкам, используя возврат нескольких значений, чтобы проверить значение ошибки. Вы можете возвратить ошибку из функций, в которых вы предварительно определили, что способны вызвать ошибку. Обычно загрязняется ваша кодовая база с if err != nil.

Слишком упрощенно для некоторых?

Эта простота имеет свою цену. Go не так выразителен, как JavaScript. Там нет значений по умолчанию. Отсутствие абстракций и обобщений делает реализацию принципов DRY более сложной и сложной, менее интуитивной.

Важно помнить, что Go еще молод. Обсуждаются дженерики, и, поскольку Gо повзрослел, они заявили о дальнейшем рассмотрении. Сообщество очень усердно работает, постоянно развивая и улучшая язык. Как и у любого языка, у Go есть свои сильные и слабые стороны. Я уверен, что если достаточное количество программистов Go почувствует потребность в определенной языковой функции, она будет реализована.

Однако, хотя может показаться, что некоторые функции отсутствуют, иногда требуется взглянуть на него под другим углом, чтобы увидеть, как вы можете достичь этого в Go.

Обычно есть способы достичь того же с помощью другого подхода, более подходящего для Go.

Когда его использовать

Можно с уверенностью сказать, что на данном этапе Go не может решить все проблемы; особенно это касается графических интерфейсов и сложных систем, требующих большой абстракции.

Но какой язык может решить все?

Используйте все преимущества Go. Если вы думаете, что язык слишком упрощен и вам трудно добавить сложность простым способом, используйте его для создания простых микро-сервисов, а не сложных систем. Используйте Go для создания сетевых инструментов и системных инструментов, а не заменяйте язык, который лучше подходит для стоящей перед вами задачи.

Поэтому самое главное – использовать правильный инструмент для работы. Если этим инструментом является Go, это значит, что Go хорош в решении данной проблемы.

Так что дерзайте.

 


.

  • December 19, 2019