Код легко читается, спецификация короткая и современная, поддержка параллельных вычислений и всех модных фичей, даже есть встроенный веб-сервер. О каком языке пойдет речь? В небольшом руководстве для новичков рассмотрим основы языка Golang и поймем причины его популярности.
Содержание:
1. Что такое Golang?
2. Преимущества Golang
3. Назначение Go
4. Установка Go
5. Синтаксис и основы языка
6. Особенности архитектуры Go
7. Преимущества Golang для начинающих программистов
Перед изучением любого языка, начинающий программист должен четко понимать конечную цель изучения. Ведь каждый из них разработан для решения определенных задач, и Golang или Go — не исключение. Google создала этот язык для решения проблем с производительностью и общим замедлением процесса разработки.
Большая сложная кодовая база корпорации, со временем, начала давать сбои — руководством было принято решение сделать новый язык, ориентированный на скорость и простоту.
Использовавшиеся до Go языки C++ и Java не обладали необходимой гибкостью и простотой построения программ такого масштаба. Созданием Golang занимались опытные специалисты Роберт Гризмер, Роб Пайк и Кен Томпсон, разрабатывавшие до этого операционную систему Inferno. Они и представили миру в конце 2009 года инструмент для решения глобальных проблем в разработке, способный сделать код более эффективным и масштабируемым.
Первоначально Go был призван решить внутренние проблемы Google, но быстро обрел общемировую популярность и его стали использовать повсеместно.
Это ли не повод начать его изучать?
GoLang обладает следующими преимуществами:
Существующие языки до недавнего времени довольно неплохо справлялись с крупномасштабным программированием. Однако, за последнее десятилетие, в вычислительной среде произошли глобальные изменения: появилось огромное количество новых сетей, увеличились объемы кластерных вычислений и размеры облачных систем.
Поэтому появление современного быстрокомпилируемого языка, эффективно запускающегося на сотнях или даже тысячах машинах — стало отличной новостью для крупного и мелкого IT-бизнеса.
Всего за шесть коротких лет с момента своего создания, Go вошел в 20-ку лучших языков программирования, сделав это за счет:
На Go можно писать почти все, но чаще всего он используется для сетевого программирования и написания клиент-серверных приложений, обработки большого количества информации, подсчета статистики, написания парсеров, блокчейн-проектов, админских и DevOps инструментов, а еще его можно использовать для написания обычных сайтов.
Официальные бинарные дистрибутивы доступны для операционных систем FreeBSD (версия 10-STABLE и выше), Linux, macOS (10.10 и выше) и Windows, а также 32-битных (386) и 64-битных (amd64) процессорных архитектур x86.
Опишем некоторые базовые моменты по установке одного из них на ваш ПК (далее приведем пример для Windows).
Шаг 1 Чтобы скачать Golang, посетите страницу загрузки на официальном сайте языка и выберите загрузочный файл, исходя из установленной у вас операционной системы.
Шаг 2 Дважды щелкните по нужному вам файлу и нажмите Run.
Шаг 3 Нажимаем кнопку Next.
Шаг 4 Выбираем директорию для установочных файлов и снова жмем Next.
Шаг 5 жмем на кнопку Finish, установка завершена.
Шаг 6 После завершения установки вы можете проверить все ли в порядке, открыв терминал и набрав:
go version
Увидев версию проинсталированного пакета — делаем вывод, что все работает нормально. Можно начинать работать!
Теперь давайте немного покодим, начнем со стандартной и предельно простой программы Hello World:
package main import "fmt" func main () { fmt.Println("Hello World! This is my first Golang program") }
Давайте пройдемся по коду построчно.
Первая строка — это объявление пакета. Каждая Go-программа должна принадлежать какому-нибудь пакету, эта конкретная программа принадлежит пакету main
. Затем мы импортируем fmt
или библиотеку форматов, которая предоставляет разработчику широкий набор функций, позволяющих форматировать вывод.
Затем мы создаем функцию main, внутри которой прописываем метод Println
, для вывода приветственного сообщения в консоль. Пока все просто.
Что такое переменная? Переменная — это не что иное, как имя, присвоенное области памяти, которой могут манипулировать программы. Каждая переменная в Go имеет определенный тип, определяющий размер и структуру памяти этой переменной, диапазон значений, которые можно хранить в этой памяти, и набор операций, которые можно применять к переменной.
Константы — это переменные с фиксированным значением. Программа не может изменять их во время своего выполнения. Эти фиксированные значения еще называют литералами. Они могут быть целочисленного типа данных, с плавающей запятой, символьные, строковые.
Константы обрабатываются также, как обычные переменные, за исключением того, что их значения не могут быть изменены после их определения.
package main import "fmt" func main () { var x int = 5 //объявление переменной x var ( a = 10 b = 15 //объявление нескольких переменных ) y := 7 // сокращенное объявление переменных const pi float64 = 3.14272345 //объявление константы var name string = "Denis" // объявление строковой переменной }
В Golang есть четыре основных типа данных, присутствующих почти в каждом языке программирования: числовой, строковый, логический, ссылочный:
В Golang также применяются три основных типа операторов: арифметические, реляционные и логические. Все они представлены на изображении ниже:
Некоторые задачи в Go невозможно выполнить без использования указателей. Как мы уже говорили, каждая переменная здесь представляет собой ячейку памяти с определенным адресом. Доступ к ней по этому адресу можно получить при помощи амперсанда (&):
package main import "fmt" func main() { // Мы передаем значение переменной в функцию x := 0 changeVal(x) fmt.Println("x =",x) // Если мы передаем ссылку на переменную, мы можем изменить значение //функции changeVal(&x) fmt.Println("x =",x) // Получаем адрес x при помощи & fmt.Println("Memory Address for x =", &x) // Мы также можем сгенерировать указатель при помощи new } func changeVal(x int) { // Не влияет на значение x в main() x = 2 } // * сигнализирует о том, что нам присылают ссылку на значение func changeXValNow(x *int){ // Изменяем значение по адресу памяти, на который ссылается указатель // * дает нам доступ к значению, на которое указывает указатель *x = 2 // в адресе памяти сохраняем значение 2 } }
Цикл — это основной итерационный механизм в информатике, он используется в случае, когда вам нужно выполнить повторяющееся действие.
Сейчас в большинстве языков программирования есть три типа циклов, а именно for, while
(контролируемый выход) и do-while
(контролируемый вход), но в Golang есть только один тип цикла — цикл for
. Синтаксис Go позволяет реализовать циклы while
с синтаксисом цикла for
:
package main import "fmt" func main() { // цикл i := 1 for i <= 10 { fmt.Println(i) i++ } // реляционные операторы ==, !=, <, >, <=, и >= // Вы также можете определить цикл for, подобный этому, но тут нужны точки с запятой for j := 0; j < 5; j++ { fmt.Println(j); } }
Конструкции, запускающие определенные участки кода, в зависимости от того, является ли условие истинным (true
) или нет (false
). В Golang они представлены «if-else
» и «switch
». Давайте посмотрим их реализацию на примере ниже:
package main import "fmt" func main() { age := 15 if age >= 16 { fmt.Println("Взрослый") } else { fmt.Println("Не взрослый") } // Вы можете использовать else для выполнения любых действий, но после совпадения // остальные условия не проверяются if age >= 16 { fmt.Println("в школе") } else if age >= 18 { fmt.Println("в колледже") } else { fmt.Println("на пенсии") } // Операторы Switch используются, когда возможные варианты-ограничены switch age { case 16: fmt.Println("может водить") case 18: fmt.Println("может голосовать") default: fmt.Println("может все") } }
Массив — это структура данных используемая для контейнеризации данных одного типа. Например, для сохранения имен учеников определенного класса. В приведенном ниже коде показано, как массивы реализованы в Golang.
package main import "fmt" func main() { //Массив содержит фиксированное количество значений одного типа. var favNums2[5] float64 favNums2[0] = 163 favNums2[1] = 78557 favNums2[2] = 691 favNums2[3] = 3.141 favNums2[4] = 1.618 // Вы получаете доступ к значению, предоставляя номер индекса fmt.Println(favNums2[3]) // Другой способ инициализации массива favNums3 := [5]float64 { 1, 2, 3, 4, 5 } // Перебор массива for i, value := range favNums3 { fmt.Println(value, i) } //Срезы похожи на массивы, но здесь не учитывается размер numSlice := []int {5,4,3,2,1} // Вы можете создать срез, определив первое значение индекса и последнее numSlice2 := numSlice[3:5] // numSlice3 == [2,1] fmt.Println("numSlice2[0] =", numSlice2[0]) //Если вы не укажете первый индекс, по умолчанию он равен 0. //Если вы не укажете последний индекс, по умолчанию он будет максимальным. fmt.Println("numSlice[:2] =", numSlice[:2]) fmt.Println("numSlice[2:] =", numSlice[2:]) // Вы также можете создать пустой срез и определить тип данных, numSlice3 := make([]int, 5, 10) // Вы можете скопировать фрагмент в другой copy(numSlice3, numSlice) fmt.Println(numSlice3[0]) // Добавлять значения в конец среза numSlice3 = append(numSlice3, 0, -1) fmt.Println(numSlice3[6]) }
Структура данных под названием «Карты» сопоставляет уникальные ключи со значениями. Ключ — это объект, который вы используете для извлечения значения. Имея ключ и значение, вы можете сохранить это значение в объекте карты. После сохранения значения его можно получить с помощью ключа.
package main import "fmt" func main() { // Карта — это набор пар ключ-значение. // Записывается так: varName := make(map[тип ключа] тип значения) presAge := make(map[string] int) presAge["Ivan Ivanov"] = 42 fmt.Println(presAge["Ivan Ivanov"]) // Получим количество элементов на карте fmt.Println(len(presAge)) // Размер меняется при добавлении нового элемента presAge["Denis Boro"] = 43 fmt.Println(len(presAge)) //Мы можем удалить значение, передав ключ для удаления delete(presAge, "Denis Boro") fmt.Println(len(presAge)) }
Функция — это группа выражений, выполняющих одну задачу. В каждой программе на Go есть как минимум одна функция — main()
. Вы можете разделить свой код на отдельные функции. Как вы это сделаете зависит от вас, но по логике деление должно быть таким, чтобы каждая функция выполняла одну определенную задачу.
При объявлении функции компилятор должен получить информацию об имени функции, типе возвращаемого значения и параметрах.
package main import "fmt" func main () { fmt.Println("5 + 4 = ", add(5,4)) fmt.Println(subtract(1,2,3,4,5)) } func add(a,b int) int { return a+b } func subtract(args ... int) { sub := 0 for _, value := range args { sub -= value } return sub }
Структура — это еще один определяемый пользователем тип данных, доступный в программировании Go, позволяющий комбинировать элементы данных разных типов. Структуры используются для представления записи.
Предположим, вы хотите отслеживать книги в библиотеке по следующим атрибутам:
В таком сценарии структуры очень полезны. Оператор struct
определяет новый тип данных с несколькими элементами для вашей программы. Оператор type
связывает имя с типом, который в нашем случае является структурой.
package main import "fmt" // структуры func main() { rect1 := Rectangle{height: 10, width: 10} fmt.Println("Rectangle is", rect1.width, "wide") fmt.Println("Area of the rectangle =", rect1.area()) } type Rectangle struct{ height float64 width float64 } func (rect *Rectangle) area() float64{ return rect.width * rect.height }
Интерфейсы представляют абстракцию поведения других типов. Интерфейсы позволяют определять функции, которые не привязаны к конкретной реализации. То есть интерфейсы определяют некоторый функционал, но не реализуют его. Звучит немного запутанно, но пример далее все прояснит:
package main import "fmt" import "math" // структуры и интерфейсы func main() { rect := Rectangle{20, 50} circ := Circle{4} fmt.Println("Rectangle Area =", getArea(rect)) fmt.Println("Circle Area =", getArea(circ)) } // Интерфейс определяет список методов, которые тип должен реализовать. // при их реализации, выполняется правильный метод // даже если оригинал упоминается с именем интерфейса type Shape interface { area() float64 } type Rectangle struct{ height float64 width float64 } type Circle struct{ radius float64 } func (r Rectangle) area() float64 { return r.height * r.width } func (c Circle) area() float64 { return math.Pi * math.Pow(c.radius, 2) } func getArea(shape Shape) float64{ return shape.area() } }
int
) можно определить методы, и в контексте ООП все такие типы будут классами (например, type newInt int
).Go
-процедуре (термин, используемый в Go для обозначения сопрограмм).unsafe
. Его особенность в том, что, будучи внешне обычным Go-пакетом, он фактически реализуется самим компилятором.В конце материала, по традиции, несколько обучающих видеороликов по теме:
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…