☑️ Язык программирования с открытым исходным кодом, поддерживаемый Google.
☑️ Легко освоить и отлично подходит для команд
☑️ Встроенный параллелизм и надежная стандартная библиотека
☑️ Большая экосистема партнеров, сообществ и инструментов
Общее
Компилируемый многопоточный язык программирования, разработанный внутри компании Google, в 2009 году.
Поддерживаемые платформы:
- FreeBSD
- OpenBSD
- Linux
- macOS
- Windows
- DragonFly BSD
- Plan 9
- Solaris
- Android
- AIX
Golang разрабатывался как язык программирования для создания высокоэффективных программ, работающих на современных распределённых системах и многоядерных процессорах.
Рекомендации о сторонних источниках
Официальная документация - go.dev/doc
Рекомендую к прочтению книгу - "Программирование на языке Go", автор Марк Саммерфильд"
хекслет - go-basics
История создания Go
Язык Go был создан Робертом Гриземером, Робом Пайком и Кеном Томпсоном — известными инженерами, которые ранее участвовали в разработке таких проектов, как Unix и язык программирования B. Основной целью создания Go было решение проблем, с которыми сталкиваются разработчики при работе с другими языками, такими как C++ и Java. Эти проблемы включали:
- Долгую компиляцию.
- Сложность управления памятью.
- Отсутствие встроенной поддержки многозадачности.
Go был разработан как язык, который сочетает в себе простоту написания кода, высокую производительность и эффективную работу с многопоточностью.
Основы
Типы данных
Типы данных определяют тип данных, которые может содержать допустимая переменная Go.
1 Базовый тип
числа, строки и логические значения
Целочисленные типы
- int8: представляет целое число от -128 до 127 и занимает в памяти 1 байт (8 бит)
- int16: представляет целое число от -32768 до 32767 и занимает в памяти 2 байта (16 бит)
- int32: представляет целое число от -2147483648 до 2147483647 и занимает 4 байта (32 бита)
- int64: представляет целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807 и занимает 8 байт (64 бита)
- uint8: представляет целое число от 0 до 255 и занимает 1 байт
- uint16: представляет целое число от 0 до 65535 и занимает 2 байта
- uint32: представляет целое число от 0 до 4294967295 и занимает 4 байта
- uint64: представляет целое число от 0 до 18 446 744 073 709 551 615 и занимает 8 байт
- byte: синоним типа uint8, представляет целое число от 0 до 255 и занимает 1 байт
- rune: синоним типа int32, представляет целое число от -2147483648 до 2147483647 и занимает 4 байта
- int: представляет целое число со знаком, которое в зависимости от платформы может занимать либо 4 байта, либо 8 байт. То есть соответствовать либо int32, либо int64.
- uint: представляет целое без знаковое число, которое, аналогично типу int, в зависимости от платформы может занимать либо 4 байта, либо 8 байт. То есть, соответствовать либо uint32, либо uint64.
Числа с плавающей точкой
- float32: представляет число с плавающей точкой от 1.4*10-45 до 3.4*1038(для положительных). Занимает в памяти 4 байта (32 бита)
- float64: представляет число с плавающей точкой от 4.9*10-324 до 1.8*10308 (для положительных) и занимает 8 байт.
В качестве разделителя между целой и дробной частью применяется точка.
Комплексные числа
- complex64: комплексное число, где вещественная и мнимая части представляют числа float32
- complex128: комплексное число, где вещественная и мнимая части представляют числа float64
Булевый тип
- bool: логический тип, true или false
Строки
- string: представляют собой неизменяемую последовательность байтов.
Содержимое строки есть не что иное, как слайс байтов ([]byte). Именно по этой причине обращение по индексу строки вернет не символ, а его юникод-значение в десятичной системе счисления.
Поддерживаются также основные операции со строками:
- Конкатенация – это операция слияния нескольких объектов (чаще всего строк) в один.
- Интерполяция – это операция замены заполнителей строки соответствующими значениями.
Строковый литерал – это константа типа string, которая является результатом слияния последовательности символов. Литералы бывают двух типов:
- интерпретируемые
символы, заключенные в двойные кавычки вида "". Текст внутри кавычек представляет собой кодировку UTF-8 отдельных символов.
- необработанные (сырые)
символы, заключенные в двойные кавычки вида ``. Их значением является строка из неявно закодированных в UTF-8 символов
2 Агрегатный тип
массивы и структуры
Массивы
представляют собой фиксированную по размеру коллекцию данных заданного типа. Выделение памяти для массива происходит в момент его инициализации, а хранится он в ней как последовательность блоков указанного типа.
Структуры
это определяемый пользователем тип, который позволяет группировать/объединять элементы, возможно, разных типов в один тип. Любая реальная сущность, которая имеет некоторый набор свойств/полей, может быть представлена как структура. Эта концепция обычно сравнивается с классами в объектно-ориентированном программировании. Его можно назвать облегченным классом, который не поддерживает наследование, но поддерживает композицию.
3 Ссылочный тип
Указатели, фрагменты, карты, функции и каналы
Указатели
это переменная, которая содержит адрес объекта.
Структуры и массивы копируются при использовании в присваиваниях и передаются в качестве аргументов функциям. С помощью указателей этого можно избежать.
Указатели хранят адреса объектов. Адреса могут передаваться более эффективно, чем реальные объекты.
Срезы
это тип данных в Go, который представляет изменяемую упорядоченную последовательность элементов.
Срезы определяются путем объявления типа данных, которому предшествуют пустые квадратные скобки ([]) и список элементов между фигурными скобками ({}).
Карты
это мощная и универсальная структура данных, которая действует как набор неупорядоченных пар ключ-значение.
Карта в Go по сути является ссылкой на хэш-таблицу. Этот тип ссылок недорог для передачи — занимает всего 8 байт на 64-битной машине и 4 байта на 32-битной машине.
- Ключи должны быть развиты и последовательного типа, например int, float64, rune, string, , массивы, структуры или указатели. Однако такие объекты, как срезы и несравнимые массивы или структуры, не могут использоваться в качестве ключей.
- Значения с другой стороны могут быть любого типа, включая другую карту, указатели или даже ссылочные данные.
Функции
в программировании является фундаментальным инструментом и представляет собой блок кода, выполняющий определенную задачу и доступный для обращения из другого места программы.
Каналы
это объект связи, с помощью которого горутины обмениваются данными. Технически это конвейер (или труба), откуда можно считывать или помещать данные. То есть одна горутина может отправить данные в канал, а другая — считать помещенные в этот канал данные.
Горутины — это легковесные потоки, которые реализуют конкурентное программирование в Go. Их называют легковесными потоками, потому что они управляются рантаймом языка, а не операционной системой. Стоимость переключения контекста и расход памяти намного ниже, чем у потоков ОС. Следовательно, для Go — не проблема поддерживать одновременно десятки тысяч горутин. Весит изначально 8кб. Каждая программа Go начинается с основной горутины, и если она завершается, все остальные останавливаются.
каналы бывают:
- небуферизованный канал блокирует отправку до тех пор, пока получатель не будет готов к чтению.
- буферизованный канал имеет передаваемую емкость, что способствует не не ожиданию получателя.
так как каналы и горутины реализуют конкуретную среду, существуют ситуации которые нужно понимать:
Чтение из канала
- Чтение из nil канала блокирует навсегда
- Чтение из пустого канала блокирует до записи в этот канал или до его закрытия
- Чтение из закрытого канала вернет zero value типа канала и false вторым значением
- Чтение из однонаправленного канала (<-chan) приведет к ошибке компиляции
Чтение из канала достаточно безопасная операция. Оно не может привести к panic из-за действий в других горутинах.
Запись и закрытие канала
- Запись в заполненный или nil канал приведет к блокировки
- Запись в закрытый канал вызывает panic
- Закрытие nil канала вызывает panic
- Закрытие закрытого канала вызывает panic
Целых три разных случая которые приведут к panic в программе.
4 Тип интерфейса
является единственным представителем семейства абстрактных типов данных в Go. Интерфейсы используются, чтобы описать, каким набором методов должна обладать его реализация. Это полезно, когда нас интересует только поведение некоторой сущности, но совсем не интересуют детали реализации. Это в свою очередь помогает снизить связность компонентов приложения и упрощает сопровождение кода.
Итого
это лишь краткое описание того что нужно знать для реализации проектов на Go. Использование с периферийным стеком смотрите на канале в подборке. Так же будет разобран каждый пункт с примерами кода.
Песочница для эксперементов- go.dev/play