Применение
Этот системный язык хорош для большинства сетевых задач, любых микросервисов и макросервисов, веб-сервисов, а также для системных инструментов – недаром его любят многие специалисты DevOps. Go находит свое применение в Machine Learning, а некоторые разработчики даже пишут с его помощью веб-сайты. Мы в своей практике обращались к Go, когда разрабатывали отдельные CRM и программные продукты для внутреннего пользования, например, для страховых компаний. В стандартном репозитории языка Go есть пакет и для мобильной разработки, данный пакет поддерживается до сих пор, хотя для этого есть более подходящие инструменты.
Go: развитие и признание
В Google разработка языка Go началась в 2007 году. До этого компания использовала Java, Python и C++, однако, они имели определенные недостатки (в частности, большое потребление памяти) или ограниченное применение. Тогда в Google начали разработку нового языка под свои нужды.
Какие требования предъявлялись к языку:
- Один исполняемый файл (отсутствие зависимостей)
- Быстрая компиляция
- Быстрый runtime (как минимум наравне с Java и С++)
- Сборщик мусора, минимизация утечки ресурсов
- Оптимизация под многопроцессорные системы
- Статическая типизация
- Минимализм
- Синтаксическая легкость
- Мультипарадигменность (императивный, функциональный, объектно-ориентированный)
Для тех, кто не работает с Go, вкратце напомним историю его создания. Спецификацию языка в Google начали продумывать в 2007 году. Релиз 1.0 состоялся в 2012 году, а в 2015 году вышел релиз 1.5, уже без единой строчки кода C++. С этого момента язык компилирует себя сам, что позволило ускорить разработку отдельных задач на Go.
Средний возраст признания нового языка в сообществе – около 10 лет, но Go уже сейчас входит в число наиболее востребованных языков. В июне 2019 года Go поднялся на 15 место по популярности в мире, согласно индексу TIOBE, прибавив за год три позиции. Среди причин его успеха можно выделить следующие:
- Сильная стандартная библиотека
- Крутой стандартный тулинг
- Наиболее необходимые функции представлены в “коробке”, а библиотеки отданы на open source
- Очень дружелюбное сообщество
Например, в стандартную библиотеку входят следующие пакеты (список неполный):
![](https://habrastorage.org/webt/8u/qj/qd/8uqjqdlmz-0crdwb5iyjkpyukdc.jpeg)
Иллюстрация – github.com/ashleymcnamara/gophers
Если вас не устраивает скорость работы вашего приложения или другие параметры, вы можете поработать с профилировщиком из “коробки”. Для этого нужно:
- Зарегистрировать импорт профилировщика: import _ «net/http/pprof»
- Добавить http-сервер для получения результатов от профилировщика: go http.ListenAndServe(«0.0.0.0:8080», nil)
Go tools
Одно из преимуществ Go – обширный набор стандартных инструментов. Мы выбрали несколько наиболее интересных утилит, на наш взгляд (на самом деле, их намного больше):
- benchcmp — сравнение бенчмарков, производительности до и после изменений
- go tool cover — анализ покрытия кода тестами
- godoc — генерация документации на основе комментариев
- goimports — анализ импортов (удаление неиспользуемых, добавление пропущенных)
- gorename — рефакторинг
- present — тулинг для презентаций
- go vet — линтер часто встречающихся ошибок
- go test — запуск тестов и бенчмарков
- go fix — фикс изменений при смене API (до релиза 1.0)
- go tool pprof — профилирование
- Go fmt — форматирование кода по code style
- Race detector — нахождение гонки данных в runtime
Конкурентность
Еще одна сильная сторона Go заключается в том, что на этом языке легко написать конкурентный код. Для этого вы просто перед вызовом функции используете ключевые слова.
![](https://habrastorage.org/webt/ik/a_/6q/ika_6qkidzulqz5in4-jjtk5lay.jpeg)
Обучение Go
Если вы хотите программировать на Go, старт займет относительно немного времени. Разработчики — Core Team — поддерживают курс A Tour of Go на нескольких языках, в том числе на русском. Этот курс можно пройти буквально за 1-3 дня. В отношении обучения Go — один из самых простых языков.
Итак, что почитать:
ORM в Go
Есть мнения, что одним из слабых мест Go являются ORM. Возможно, отчасти это происходит из-за того, что язык молод — в нем только начинают разрабатывать многие необходимые инструменты. В частности, для работы с базами данных можно использовать пакет database/sql. Какие требования предъявляются к пакету:
- Общий пакет для всех sql баз данных
- Портируемый: не содержит никаких особенностей в области работы с базами данных. В идеале все должно корректно работать, если вы поменяете драйвер.
- Преобразование типов Go в стандартные типы базы данных (при этом должна быть возможность обработки специфичных типов)
- Содержит пул соединений
- Thread-safety для горутин
Пример SELECT запроса с использованием database/sql
defer rows.Close()
for rows.Next() {
var message string
err := rows.Scan(&message)
if err != nil {
log.Panic(err)
}
fmt.Println(message)
}
if err := rows.Err(); err != nil {
log.Panic(err)
}
Как видно из примера, очень много шаблонных действий придется выполнять каждый раз. Например:
- закрывать объект rows: defer rows.Close()
- проверять на ошибки err := rows.Err(); err != nil т.к. не понятно по какой причине rows.Next() вернул нам значение false
Из всего этого хочется использовать что то более универсальное и простое, например, ORM.
Виды реализаций ORM
Когда перед разработчиками встает вопрос выбора ORM для работы с Go, они зачастую ориентируются по рейтингу на гитхабе. Когда мы выбирали ORM для себя, лучший рейтинг имел Beego (18 тысяч “звездочек”). Однако, на практике ORM входит в состав фреймворка, поэтому оценка не вполне объективна (если выбирать исключительно ORM). Также в числе лидеров Gorm, который развивается с 2013 года, поддерживает транзакции и имеет много других преимуществ.
![](https://habrastorage.org/webt/4t/lk/up/4tlkupvoryxwcybeiobknmqkyze.jpeg)
Однако, как показал наш опыт знакомства с Gorm, при его использовании возможны определенные проблемы, особенно при тестировании: например, гонка данных или c удалением foreign key. Можно предположить следующие причины подобных ошибок в Gorm:
- Коммиты сразу в master
- Отсутствие тегов
- Непредсказуемый sql билдер
На данный момент мы в своей работе отдаем предпочтение нескольким ORM, которые не используют interface{} — это Kallax, Reform и Sqlboiler. Обычно задействуем пакет Golang для миграций и репозиторий orm-bench с бенчмарками ORM на Go. При этом не стоит гнаться только за бенчмарками. Чаще скорость не так важна, как качество кода и его функциональность.
Подводя итоги
К преимуществам языка Go для разработчика и для бизнеса можно отнести повышение производительности разработки, возможность использовать меньшее количество серверов, синтаксическую легкость и быстрые сроки обучения новых разработчиков, большой набор инструментов и дружелюбное комьюнити. Несмотря на то, что это молодой язык, он постоянно растет и развивается. Особенности Go делают его оптимальным языком для выполнения самых разных проектов, от сетевых задач до микросервисов и блокчейна.
Статья подготовлена на основе нашего доклада на митапе Hot Backend в Самаре.
Комментарии (14)
TonyLorencio
28.06.2019 17:19+1
ababo
28.06.2019 17:56Не рекомендую `GORM` и подобные ему ORM. Закопаетесь в изучении нюансов маппинга их конструкций на нативный SQL, вместо того, чтобы писать SQL напрямую. Мне лично очень нравится `reform`, писал на нём три проекта, остался доволен.
JekaMas
29.06.2019 09:04+1Когда был в Lazada, то мы писали очень шустрое решение без кодогенерации — github.com/lazada/sqle. Посмотрите, может и вам подойдёт.
GHostly_FOX
29.06.2019 09:58+1Для меня как-то сухая статья.
Не понятно почему сделали выбор с торону этих ORM!?
Можно было бы привести примеры работы с разными ORM ^(SSul Автор
29.06.2019 15:24В сторону этих ORM выбор был сделан из-за безопасности типов. В строго типизированном языке принимать на вход, например, в метод Save(value interface{}) пустой интерфейс опасно, можно легко ошибиться. Когда можно использовать кодогенерацию со строгой типизацией. В поиске примеров select запросов лучше всего посмотреть репозиторий orm-bench
VolCh
29.06.2019 10:46+1А можно указать какие ORM паттерны эти библиотеки реализуют? Особенно интересно какие из них реализуют DataMapper.
apapacy
29.06.2019 12:58+1Чего хотелось бы от orm
1) работа с переводимыми полями.
Конечно, переводимые поля это всего лишь еще одна связанная таблица. Но, согласитесь, что если в orm есть встроенная поддержка translatable это сразу в два раза упрощает работу с данными (например как в php doctrine)
2) автогенерация миграций
Многие базы данных поддерживают, но не всегда это равноценный функционал. Поэтому часто встречаю утверждения что в ткакой-то orm «тоже есть миграции»
Пока что я нашел только две orm c максимальной поддержкой миграций — php doctrine и javascript/typescript typeorm
Под максимальной поддержкой миграций я подразумеваю
1) автогенерацию кода на языке программирования orm (не sql-скрипты а например php-скрипты)
2) автогенерацию на основании сравнения текущей реальной базы данных с моделью (а не со схемой состояния которая была сгенерирована при прошлой миграции)
3) возможность кастомизировать полученные автогерерируемые скрипты
Интересно было бы услышать как Вы работали с переводимыми полями и миграциями. Ну а что касается конкретно go тут еще добавляется известная проблема с nullable полями
Действительно это интересный у Вас опыт но самые интересующие разработчиков вопросы пока что не нашли своего долдного освещения. А было бы очень интересно.SSul Автор
29.06.2019 19:22+1Для переводимых слов обычно используем отдельную сущность — словарь. Для миграций — пакет golang-migrate. А с nullable полями всегда непросто, это решается на уровне работы по валидации данных
GHostly_FOX
29.06.2019 19:26+1Вот об этом я и говорю…
Тема не была раскрыта полностью. Много вопросов которые можно было избежать если бы пересичленные ORM были приведены в более детальном сравнении с примерами кода их использования. А не объяснять потом в комментариях…SSul Автор
29.06.2019 20:43+3Спасибо за рекомендации. Наш доклад на Hot Backend был направлен в первую очередь на знакомство с языком Go, на детальные вопросы мы отвечали после доклада. Будем иметь в виду для следующих публикаций)
SONANT
Есть такая штука
Используйте её пожалуйста, пощадите читателя.