Go, также известный как Golang - это структурный, компилируемый язык программирования общего назначения. Его создатели - бывшие сотрудники известной IT-корпорации Google. Программисты ценят Golang за производительность и лаконичный синтаксис, заказчики ПО - за надежность кода и относительно быструю разработку. От C++, Python и других объектно-ориентированных языков Го отличает отсутствие классов и объектов. В нем используются структуры и функции.
Особенности языка
- Упрощенный синтаксис.
Программисту на Go не обязательно следить за расстановкой точек с запятой и прочими правилами синтаксиса. Компилятор сам об этом позаботиться. - Автоматизированная память.
От переполнения памяти программы на Го защищает сборщик мусора, в автоматическом режиме обрабатывающий нужные ячейки. За счет этого код пишется быстрее, чем на С++ или С#. - Легкое форматирование строк.
С помощью единственной команды gofmt можно привести строки программы к единому формату: выровнять отступы, выделить колонки и т. д. Команда gofix, в свою очередь, ищет устаревшие синтаксические конструкции, не соответствующие действующим нормам. - Доступные инструменты тестирования.
В Golang легко можно отслеживать несовместимость типов, перегруженные конструкции и прочие уязвимости. - Исключение состояния гонки.
В многопоточных системах функции могут исполняться в неверном порядке - это и называется состоянием гонки. Обычно такая ошибка проявляется случайно и с трудом поддается ручному отслеживанию. Локализовать проблему помогает флаг race, выставляемый на этапе компилирования или тестирования кода. - Функциональный стиль.
В Go место объектов и классов занимают функции. Они передаются в качестве аргументов и могут выступать в роли пользовательских типов данных. В языке также присутствуют замыкания и другие полезные фишки, связанные с функциональным стилем программирования.
Преимущества и недостатки Go
Golang обладает рядом объективных плюсов.
- Статическая типизация.
Для стандартных типов переменных Go использует строгое определение. Это значит, что, например, в изначально числовую переменную невозможно случайно записать строку и тем самым вызвать ошибку. В то же время динамическая типизация с присущей ей плюсами доступна для пользовательских типов переменных. - Высокая скорость обработки данных.
Go выделяется среди конкурентов рекордно коротким временем компиляции кода. При этом он занимает заметно меньше оперативной памяти, чем С++ и C#. - Поддержка параллельных потоков.
Функции-горутины в Go работают параллельно, равномерно распределяя ресурсы процессора. Механизм использования параллелей достаточно прост даже для новичков. - Работа с юникодом.
Го поддерживает все символы из Юникода, то есть фактически все алфавиты мира. - Большой спектр библиотек.
В стандартном Golang представлено множество библиотек для веб и десктоп разработки. Есть поддержка библиотек С и С++. Кроме того, язык активно пополняется качественными пользовательскими решениями. - Авторитет создателей.
Go создали инженеры-практики из компании Google - Роб Пайк и Кен Томпсон. При разработке языка они руководствовались принципами эффективности и устойчивости кода при использовании даже в самых крупных веб-системах. Сейчас Го активно поддерживается сообществом и развивается в соответствии с требованиями времени.
Как у любого языка программирования, у Go есть и свои минусы.
- Отсутствие возможностей ООП.
Несмотря на то что функции в Golang работают не хуже объектов и классов, многим разработчикам сложно перестроиться с ООП принципов на другой формат построения кода. Создателям языка пришлось отказаться от привычных подходов ради повышения производительности платформы. - Работа типов переменных с перечислениями.
Эти типы представлены в Go как независимые целочисленные константы, из-за чего возникают некоторые неудобства - например, при работе с циклом Switch. - Отсутствие структурной обработки исключений.
Постоянный возврат ошибок замедляет работу с кодом и отладку программ. - Затрудненный переход с других платформ.
В некоторых случаях Го работает по своей особенной логике, непривычной для программистов, освоивших до этого Python, Ruby или C++. Это касается семантики присваивания типов, операций с массивами и других вещей.
Где применяется Go
Благодаря своей высокой производительности, Go часто используется в создании крупных серверных приложений и многопоточных вычислительных систем. Скорость ответа сервера при программировании на Го достигает 10-20 мс против привычных для других языков 200 мс.
На Golang также нередко пишут микросервисные приложения - то есть программы, состоящие из небольших, формально независимых, но связанных между собой сервисов.
В целом Go считается языком программирования общего назначения. На нем можно создать и десктопную программу, и код для обработки исследовательских данных. Правда, интерфейс программы придется делать с помощью вспомогательных инструментов, например, WinAPI.
Основы программирования Golang
Разберем базовый синтаксис и особенности языка на конкретных примерах.
Объявление переменных и массивов
Всего в Golang предусмотрено 17 типов переменных. Из них 11 целочисленных, различающихся по загрузке памяти и используемой системе счисления. Кроме целых, в Го доступны дробные и комплексные числа, а также строки и логические переменные.
Значение переменной можно задать сразу во время объявления.
var a int = 1
Существует и краткая версия записи.
a := 5
Переменную можно объявить и без присвоения ей конкретного значения. При этом любая объявленная переменная должна быть использована в коде, иначе программа не скомпилируется.
По умолчанию числовым переменным присваивается значение 0, логическим - false, а строковым - пустая строка.
Последовательности элементов, или массивы, задаются следующим образом.
var array [3]int = [3]int{1,2,3}
Краткая запись выглядит так.
array := [3]int{10, 11, 12}
При объявлении массива обязательно указывается количество включенных в него значений и их тип.
В Го также существуют слайсы - массивы со свободным количеством элементов.
var array []int = []int{1,2,3}
Размер слайса может меняться при необходимости.
Условия и циклы
If - базовый оператор условия для любого языка программирования. В Го он работает по привычной всем разработчикам схеме.
Возьмем пример со сравнением двух чисел.
package main
func main() {
a := 2
b := 4
if a < b {
println("a меньше b")
} else if a > b {
println("икс больше игрека")
} else {
println("числа равны")
}
}
Кроме условия If, в коде примера обозначена главная функция программы - main.
В цикле For также нет ничего сложного.
package main
func main() {
for a:= 1; a <= 10; a++ {
println(a)
}
}
Здесь мы выводим на экран числа от 1 до 10.
Цикл может быть и бесконечным. Прервать бесконечную обработку позволяет команда break.
package main
func main() {
a := 0
for {
println("Бесконечный цикл")
if a == 10 {
break
}
a++
}
}
Функции
Можно сказать, что на функциях строится основная часть кода в Golang. Функции используются для быстрой вставки одинаковых фрагментов программы и экономии времени. Рассмотрим самый простой пример - функцию сложения. Прописав ее один раз, перед основной функцией, мы можем выполнить операцию сложения в любой момент с любыми аргументами.
package main
func Sum(x, y int) int {
return x+y
}
func main() {
a:=Sum(2,5)
b:=Sum(4,10)
println(a)
println(b)
}
В функцию можно добавить несколько действий и получить все необходимые значения.
package main
func SumAndSub(a, b int) (int, int) {
return a + b, a - b
}
func main() {
x,y:=SumAndSub(2,5)
println(x)
println(y)
}
Go routine
Горутины - это параллельно, то есть одновременно, выполняемые процессором функции. Обычную функцию можно превратить в горутину с помощью оператора go.
Горутины применяются для ускорения работы серверов при выполнении объемных многопоточных программ. Разработчику не приходится самостоятельно следить за распараллеливанием - за него это делает специальная библиотека. Ресурсы процессора при этом расходуются максимально равномерно.
Каналы
Каналы позволяют независимым горутинам передавать друг другу хранящиеся в них данные. По сути, каналы используются как буфер обмена внутри программы.
Каждый канал принимает и передает только заранее определенный тип данных - числовой, логический или строчный.
Для предотвращения ошибок в каналах предусмотрены блокировка и очередь. Данные передаются строго в пустой канал. На функцию-отправитель накладывается блок, пока принимающая горутина не считает отправленную информацию. При этом функция-получатель блокируется, пока канал пуст.
Синтаксис каналов выглядит так.
intChannel := make(chan int)
Через оператор <- в канал передаются данные.
strChannel <- ‘Hello’
Пакеты
Программы на Go, как правило, состоят из множества отдельных файлов, или так называемых пакетов. В начале каждого примера из этой статьи мы прописывали оператор package, который открывает новый пакет и дает ему имя.
Функции из одного пакета Го можно использовать в другом. Для этого нужно импортировать нужный файл через стандартную команду import. Далее следует прописать название импортированного пакета и через точку - название функции.
package main
import "math"
func main() {
s:= math.Sum(5,10)
}
Пакеты упрощают структурирование программы и экономят время разработчика при написании кода.
Заключение
Go - язык, применяемый для разработки масштабных, многопоточных серверных приложений. Код на Го отличается устойчивостью, скоростью исполнения и достаточно простым синтаксисом. Будучи относительно молодым, Go стремительно набирает популярность и развивается, составляя конкуренцию распространенным C++ и Python.