golang

От C до Go. Как Golang объединил лучшие черты своих предшественников

  • среда, 2 августа 2023 г. в 00:00:20
https://habr.com/ru/companies/serverspace/articles/751766/


В программировании постоянно разрабатываются новые языки. В каждом из них разработчики стремятся расширять возможности предыдущих технологий. Одним из таких примеров является язык Go, или Golang (Google language). Разработанный в компании Google, Golang был создан с целью объединить черты своих предшественников и предложить программистам новый инструмент для создания приложений. Когда создатели Golang приступили к разработке, они учитывали опыт различных языков, таких как C, C++, Java и Python.

Наша команда активно использует Golang для работы, например с Terraform-провайдером, поэтому мы решили разобрать его особенности подробнее. В этой статье мы рассмотрим историю языка, почему он стал таким востребованным среди разработчиков, разберем, какие черты заимствованы от C и других языков, а также дадим небольшую подборку материалов для самостоятельного изучения.

C и C++


Начнем с истоков. Как уже было сказано многие языки программирования появляются из других языков, как бы парадоксально это не звучало. Объединяя преимущества и убирая недостатки одних – и создаются новые инструменты. Так, язык программирования C был разработан в начале 1970-х годов в лаборатории Bell Labs (Bell Telephone Laboratories) компании AT&T (American Telephone and Telegraph Company). Его создателями являются Деннис Ритчи и Кен Томпсон.

В начале 1970-х годов в Bell Labs для разработки операционной системы UNIX был создан язык программирования «B», который был расширением языка BCPL. Однако «B» имел некоторые недостатки. В связи с этим, Деннис Ритчи и Кен Томпсон начали разрабатывать новый язык, в который внесли множество улучшений и новых функций. Первый прототип языка получил название NB (New B). Позже язык был переименован в «С» в отношении его предшественника «B». Этот выбор имени имел и символический смысл – «С» был «следующим» языком после языка «B». A, B, C…ну, вы поняли.

Язык C стал популярным среди разработчиков и быстро распространился, прежде всего благодаря тому, что с его помощью была написана операционная система UNIX. C стал стандартным языком программирования для разработки системного и прикладного программного обеспечения.

В 1978 году была выпущена первая версия стандарта ANSI C (American National Standards Institute C), что стало ключевым моментом в истории развития языка. В последующие десятилетия язык C оставался одним из самых популярных и широко используемых, став основой для множества других языков, таких как C++.

Перейдем к C++, до 2007 года он был одним из самых популярных языков программирования. Создан он был Бьёрном Страуструпом с целью разработки такого инструмента, который позволял бы ему более эффективно писать программы для UNIX.



Бьёрн Страуструп
Бьёрн Страуструп – датский ученый, программист, создатель языка программирования C++. Он объединил возможности языка C с концепциями объектно-ориентированного программирования.


Страуструп хотел расширить возможности C, добавив в него некоторые возможности объектно-ориентированного программирования (ООП), чтобы сделать код более структурированным и упорядоченным. В 1983 году он создал прототип языка, который назвал «C with Classes» (C с классами), что стало первым шагом к созданию C++. Окончательная же версия языка была выпущена в 1985 году, где уже были реализованы основные концепции: классы, наследование, инкапсуляция и полиморфизм.

Google и Go


В 2007 году Google столкнулся с проблемами в создании крупномасштабных приложений. Так как это крупная компания, она, конечно, имеет большое аппаратное и программное обеспечение. Поэтому проблемы, связанные с многоядерными процессорами, сетевыми системами, массивными вычислительными кластерами и моделью веб-программирования, скорее просто обрабатывались, чем действительно решались.

Google использовал комбинацию языков C++, Python и Java, но ни один из них не обеспечивал той эффективности, простоты и масштабируемости, в которых нуждался Google. Если быть точнее, то серверная часть была написана на C++, а для других использовались Java и Python. Тысячи инженеров работают в Google над кодом, поэтому изменения происходят здесь на всех уровнях дерева. Большая специализированная распределенная система сборки делает разработку в таком масштабе осуществимой, но она все равно остается большой.



Все это работает на миллионах машин, которые рассматриваются как небольшое количество независимых вычислительных кластеров, объединенных в сеть. Короче говоря, разработка в Google могла быть довольно медленной.

В принципе из-за этого и была собрана группа из разработчиков, в которую вошли Роберт Гризмер, Роб Пайк и Кен Томпсон, сотрудники Google. Они должны были разработать такой язык, который сочетал бы в себе простоту и эффективность C и C++, с возможностями параллельного программирования и современным подходом к разработке.



Цель проекта – создать язык, который был бы таким же быстрым, как C++, простым в написании, как Python, и масштабируемым, как Java.

Разработка началась в сентябре 2007 года. По мере развития, конечно, к ним присоединялись и другие программисты. В январе 2008 года началась работа над исходным компилятором.
Первая версия Go была выпущена в ноябре 2009 года, и с тех пор она претерпела несколько крупных релизов. Потребовалось еще несколько лет, чтобы выпустить первую стабильную версию Go в марте 2012 года. Подробнее о выпуске можно прочитать в примечаниях.

С момента своего первого выпуска Golang сильно изменялся, особенно в синтаксисе и семантике языка. Google попытался удалить следы C из языка, сделав его структуру еще более простой в использовании. В результате Golang стал более дружелюбным к разработчикам, которые не имеют опыта работы с другими языками программирования.

Самый значимый релиз был представлен в августе 2015 года – Golang 1.5 (примечания к выпуску), где инструментарий компилятора был полностью преобразован с C на Go. На этом этапе Golang принял тот вид, к которому стремились его авторы. Дальше он уже переходил в фазу доработки и создания новых полезных фич (дополнительных библиотек, фреймворков, инструментов и т.п.).

Самые большие изменения в реализации из примечаний к выпуску:
  • Компилятор и среда выполнения теперь полностью написаны на Go (с небольшим количеством Ассемблера).
  • Сборщик мусора теперь является параллельным и обеспечивает значительно меньшее время простоя.
  • По умолчанию программы Go запускаются с GOMAXPROCS установленным количеством доступных ядер; в предыдущих выпусках по умолчанию он был равен 1.
  • Поддержка внутренних пакетов теперь предоставляется для всех репозиториев, а не только для ядра Go.
  • Команда go теперь обеспечивает экспериментальную поддержку внешних зависимостей «vendoring».
  • Новая go tool trace команда поддерживает детальную трассировку выполнения программы.
  • Новая go doc команда настроена для использования в командной строке.

Талисман


Талисман у Go – Суслик. Интересно, что первоначальная версия талисмана была создана задолго до рождения языка. Его создала Рене Френч для рекламы радиостанции WFMU в Нью-Джерси. Рене Френч было поручено создать футболку для ежегодного сбора средств.



Далее суслик появился в Bell Labs в качестве аватара Боба Фландрена в почтовой системе Bell Labs. Другие рисунки Рене стали аватарами для ken, r, rsc и других. Когда начался проект Go, необходимо было разработать логотип и Рене вызвалась его нарисовать. Он был изображен на первой футболке Go и на сайте Google Code.



Для запуска с открытым исходным кодом в 2009 году Рене предложил адаптировать суслика WFMU в качестве талисмана. И родился суслик-гофер.



В итоге он претерпевал еще несколько изменений в связи с подготовкой мерча и различными событиями и окончательно стал символом языка.



Особенности языка Go


Golang был разработан с учетом особенностей разных языков программирования, включая C, C++, Java, Python и другие. В результате Golang заимствовал и улучшил некоторые черты от своих предшественников, рассмотрим некоторые из них:

Из C и C++
  • Синтаксис Go схож с языками из семейства C (такими как C и C++). Включает в себя использование фигурных скобок для блоков кода, точку с запятой в качестве разделителя, операторы присваивания и т.д.
  • Golang является компилируемым языком программирования, что позволяет ему достигать высокой производительности. Исходный код на Golang компилируется в машинный код, что делает его эффективным в выполнении.
  • Go поддерживает указатели, что позволяет эффективно работать с памятью и применять указатели для передачи данных по ссылке.
  • Строки в Golang заключаются в двойные кавычки, что делает их удобными для работы с текстовыми данными.
  • Горутины в Golang – это легковесные потоки, а многопоточность в Golang реализуется через механизм горутин. Этот подход аналогичен модели потоков C и C++, но более прост и эффективен.
  • В Golang используется возвращаемое значение ошибки для обработки ошибок в функциях.
  • Golang занимает промежуточное положение между скоростью выполнения C/C++ и удобством Python/Java.

Из Python
  • Golang также как и Python, стремится к простоте и читаемости синтаксиса. Это делает код на Golang более понятным и читаемым, что упрощает разработку и поддержку программ.
  • Как Python и Java, Golang также обладает сборщиком мусора (garbage collector), что позволяет автоматически управлять выделением и очисткой памяти, освобождая разработчика от необходимости делать это вручную.
  • Golang предоставляет набор встроенных функций и библиотек, аналогичных некоторым из тех, которые доступны в Python. Например, работу с файлами, строками, временем, математическими операциями и т.д.
  • Как и в Python, Golang предоставляет свой встроенный тестовый фреймворк для написания модульных тестов и обеспечения стабильности кода.

Из Java
  • Сборщик мусора есть как в Python, так и в Java, поэтому Go заимствовал эту функцию из обоих языков.
  • Golang также поддерживает интерфейсы, которые позволяют абстрагироваться от конкретной реализации и создавать более гибкий и расширяемый код.
  • Как и в Java, Golang предоставляет механизм обработки ошибок с использованием исключений. Однако, в отличие от Java, Golang больше рекомендует использовать возвращаемые значения ошибок для их обработки, чем исключения.
  • Подобно Java, Golang использует пакетную структуру, что делает организацию и управление проектами более удобным и позволяет избежать конфликтов имен.
  • Golang является языком со строгой статической типизацией. Это означает, что типы данных должны быть объявлены заранее, что обеспечивает более надежный код и облегчает его отладку.


Несмотря на то, что Golang заимствовал некоторые концепции из Python, он также представляет свои уникальные особенности. Помимо простоты, эффективности и масштабируемости, Go обладает несколькими фичами, которые делают его популярным среди разработчиков:

Простотой синтаксис


Официальная документация Go занимает около 50 страниц, просто читается и содержит примеры. Базовый синтаксис в основном относится к семейству C, с некоторым вдохновением от Pascal, Modula и Oberon для деклараций и пакетов. Подход со статически связанными двоичными файлами еще больше снижает сложность времени выполнения.
Пример:
package main

import "fmt"

func main() {

    // Строки могут быть сложены с помощью символа `+`.
    fmt.Println("go" + "lang")

    // Целый числа и числа с плавающей точкой.
    fmt.Println("1+1 =", 1+1)
    fmt.Println("7.0/3.0 =", 7.0/3.0)

    // Логические значения с логическими операторами
    fmt.Println(true && false)
    fmt.Println(true || false)
    fmt.Println(!true)
}

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


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

Наличие «сборщика мусора»


Go использует алгоритм сборки мусора для автоматического определения неиспользуемых объектов и освобождения занимаемой ими памяти. Основным алгоритмом сборки мусора в Go является трёхцветная сборка мусора (tricolor garbage collection), который основан на алгоритме «пометки и освобождения» (mark and sweep). Процесс сборки мусора в Go происходит в фоновом режиме, что позволяет продолжать работу программы без прерываний.

Компилируемость


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

Инструменты разработчика


В Go есть инструменты, которые ускоряют разработку и помогают решать разные задачи:
  • go toolchain – комплект инструментов Go включает в себя компилятор, средства форматирования (gofmt) и статического анализа (go vet), а также утилиту для работы с зависимостями (go mod).
  • gofmt – инструмент для автоматического форматирования исходного кода в соответствии с официальным стилем Go.
  • godoc – найдет комментарии и подготовит из них мануал к программе.
  • go vet – утилита для статического анализа и поиска потенциальных ошибок в коде.
  • go get – команда для загрузки и установки пакетов из репозитория.
  • go mod – инструмент для управления зависимостями в проекте с использованием модулей Go.
  • go test – команда для запуска тестов в проекте.
  • Delve – отладчик для Go, который позволяет отлаживать код с использованием командной строки или интегрированной среды разработки (IDE).
  • Gin или Echo – популярные веб-фреймворки для создания веб-приложений на Go.
  • Cobra – библиотека для создания удобных командной строки интерфейсов (CLI) для ваших приложений.
  • gRPC и Protobuf – библиотеки для реализации механизма удаленного вызова процедур (RPC) с использованием Protocol Buffers.
  • Swagger и go-swagger – инструменты для создания и документирования API с помощью спецификации OpenAPI (Swagger).
  • sqlx – библиотека для упрощения работы с базами данных SQL.
  • testify – библиотека для упрощения написания и запуска тестов.
  • goimports – инструмент для автоматического добавления или удаления импортов в Go-файлах.
  • gas – найдет уязвимости.
  • typecheck – проверяет соответствие типов в коде.


Для чего используется Golang


Сетевые и веб-серверы, микросервисы, распределенные системы, облачные сервисы и DevOps, веб-разработка, командные интерфейсы (CLI), базы данных и хранилища, проекты с открытым исходным кодом.

Облачная разработка
Go удобен для создания облачных приложений благодаря параллельным и сетевым возможностям, а также высокой степени переносимости. Крупные проекты с открытым исходным кодом, такие как Kubernetes, Docker и Terraform, работают на Go.

Сетевые службы
Параллелизм — это важное свойство для сетевых приложений, и язык Go предоставляет собственные инструменты для реализации параллельных операций, такие как горутины и каналы, которые идеально подходят для таких задач. Поэтому многие проекты на Go становятся полезными для разработки сетевых приложений, распределенных задач и облачных сервисов, таких как API, веб-серверы и простые фреймворки для веб-приложений.

Автономные инструменты и утилиты
Поскольку программы на Go быстро запускаются и могут быть легко упакованы для дальнейшего распространения, они полезны для разработки утилит и других инструментов. Экземпляром является сервер доступа Teleport (в том числе для SSH). Teleport можно быстро и просто установить на серверы, загрузив готовый двоичный файл или создав его из исходного кода.

Материалы по Golang



Видео



Курсы



Чуть-чуть рекламы: На виртуальных машинах Serverspace можно развернуть среду разработки для программирования на Go. Вы можете подобрать конфигурацию, необходимую для установки, с помощью калькулятора на сайте или в панели. Также управлять облачной инфраструктурой можно с помощью файлов конфигураций Terraform-провайдера.