Главная / Курсы / Golang / Введение
# Глава 1. Введение Язык [Go](https://ru.wikipedia.org/wiki/Go) — компилируемый многопоточный язык программирования, разрабатываемый внутри компании Google с 2007 года. Непосредственным проектированием занимались Роберт Гризмер, Роб Пайк и Кен Томпсон. Робер Гризмер работал над V8 JavaScript engine — движком JavaScript и WebAssembly для браузера Chrome, Java HotSpot — виртуальной машиной Java (JVM — java virtual machine), над языком программирования Sawzall. Роб Пайк — один из создателей кодировки UTF-8, участвовал в создании операционных систем Plan 9 и Inferno. Кен Томпсон — один из создателей Unix и UTF-8. Официально язык представлен в ноябре 2009 года. Язык имеет свою философию, основанную на минималистичности языковых средств и необходимости обработки ошибок по месту их возникновения. Цель данного курса — познакомить читателя с языком Go на достаточном уровне, чтобы иметь твердую базу для уверенного использования языка. ## Ключевые особенности ### Производительность и простота работы с большим количеством конкурентных запросов Язык проектировался с целью эффективного решения задач с поддержкой десятков тысяч конкурентных запросов. ### Быстрая скорость компиляции Существуют интерпретаторы языка Go, однако зачастую в них нет надобности, потому что язык Go компилируется быстро. ### Отсутствие синтаксических излишеств С точки зрения разработчиков языка Go многие возможности большинства языков программирования не используются в реальной разработке. Поэтому хорошо бы иметь язык, который не обладает излишествами. Программы, не усложненные дополнительными языковыми конструкциями, получаются легко читаемыми. Язык Go — язык с простым синтаксисом. Код, написанный на Go разными разработчиками, выглядит одинаково. Однако у этого есть и свой недостаток. Невыразительный синтаксис языка вынуждает писать на нем многословный код. Поэтому Go вряд ли придется по вкусу ценителям однострочников на Python. Зато большинство программистов легко осваивают синтаксис Go и сразу переходят к решению реальных задач. ### Отсутствие исключений В Go отсутствует механизм исключений (exceptions). Разработчик не сможет написать объемный код, бездумно обернуть его конструкцией `try-catch` и в блоке `catch` ловить все исключения подряд. Вместо этого Go вынуждает задумываться над способом обработки для каждой возможной ошибки: ```go rowsInserted, err := Update(table, newData) if err != nil { // ... } ``` В этом примере функция `Update` возвращает пару значений: количество вставленных в таблицу записей и ошибку. Разработчику приходится осознанно принимать решение о том, как поступить с конкретной ошибкой по месту ее возникновения. ### Горутины Приятная возможность языка Go — это горутины — легковесные потоки, которые может создавать программа. Горутина требует существенно меньше ресурсов, чем процесс на уровне операционной системы. ### Принцип «не используешь — не подключай/не объявляй» В Go существует следующее правило: не используешь — не подключай/не объявляй! Зависимости, которые подключены, но не используются, являются программной ошибкой. Такая программа скомпилирована не будет. Аналогично неиспользуемая переменная также является ошибкой. ### Кроссплатформенность Поддержка официального компилятора предоставляется для многих операционных систем, в том числе для Windows, Linux и macOS. В большинстве случаев программу на Go удается собрать в единый исполняемый файл со всеми зависимостями, что существенно упрощает перенос программы на целевую систему. ### Сборщик мусора Сборщик мусора обеспечивает безопасную работу с памятью. ## Структура проекта Разработчиками языка Go не дается четких указаний на тему того, как должен быть структурирован проект. Однако многие программисты придерживаются одного популярного способа. Вот как может быть устроен типичный проект: ``` . ├── cmd │ └── main.go ├── internal ├── pkg ├── vendor ├── go.mod ├── go.sum └── README.md ``` ### /cmd Здесь находятся основные файлы. Чаще всего они небольшого размера. Так, в файле `main.go` может находиться маленькая функция `main`, которая использует весь остальной код из `internal` и `pkg`. Также файл `main.go` иногда называют именем проекта. Например, для проекта с именем `awesome_cats` такой файл можно назвать `awesome_cats.go`. ### /internal Внутренний код проекта, который не предназначен для использования сторонними приложениями и библиотеками. ### /pkg Код, который могут использовать сторонние приложения и библиотеки, ожидая автономной работы от него. Некоторые программисты вовсе не используют эту директорию. Если у вас небольшое самостоятельное приложение, то необходимости в `pkg` нет. Однако, если проект разрастается, стоит задуматься над тем, чтобы создать эту директорию. ### /vendor Зависимости, которые использует проект, могут быть загружены в папку `vendor`. Папка `vendor` позволяет собрать проект, использующий сторонние библиотеки, на чистой системе без необходимости заходить в интернет. Создать папку `vendor` и выгрузить все зависимости в нее: ``` go mod vendor ``` ### go.mod Файл, содержащий информацию о проекте. Создать `go.mod`: ``` go mod init example.com ``` Вместо `example.com` обычно указывают имя сайта вашего проекта или, например, репозиторий на `github`. Если вы не планируете выкладывать проект в открытый доступ, то можно указать просто имя вашего проекта. Эта строка используется также для подключения внутренних зависимостей, которые пишите и используете вы сами. Помимо этого `go.mod` включает в себя информацию о версии компилятора языка Go, которую вы используете, а также о внешних зависимостях и их конкретных версиях. ### go.sum Этот файл поддерживает контрольную сумму, и генерируется автоматически. Вам не нужно редактировать его. ## Базовый синтаксис Знакомство с языком Go мы начнем, рассматривая базовый синтаксис и выполняя небольшие учебные задания. Цель данного раздела — вводное знакомство с языком с тем, чтобы потом рассмотреть многие его частности более подробно. Итак, поехали! Вот, как выглядит hello world на языке Go: ```go {.example_for_playground} package main // имя текущего пакета import "fmt" // импортируемый пакет fmt func main() { // точка вход в программу fmt.Println("Hello world!") } ``` Первая строка программы — имя текущего пакета. Каждая программа на языке Go состоит из множества файлов, объединяемых в так называемые пакеты. Пакеты объединяются в модуль. Главный пакет называется `main`, также, как функция определяющая точку входа в программу. После директивы `import` идет список пакетов, которые необходимо включить. В данном случае мы включили пакет `fmt`, чтобы использовать функцию `Println()` из него, которая печатает на экран текст и делает перенос на следующую строку. Текст после символов слешей `//` является однострочным комментарием и игнорируется компилятором. Многострочные комментарии также, как и в языке C, выделяются следующим образом: ```go /* Многострочный комментарий */ ``` ## Стиль именования В Go всюду рекомендуется использовать "стиль верблюда", за исключением имени проекта, папок и файлов. В последних трех случаях используется "стиль змейки". Например, переменную можно назвать `awesomeUserVariable`, файл — `awesome_user_file.go`. При этом принято следующее соглашение: имена, которые начинаются с прописных букв, доступны из пакетов, которые их импортируют. В противном случае они доступны только внутри своего пакета. ## Встроенные типы данных - `int8` — 1 байт. Целое число от -128 до 127. - `int16` — 2 байта. Целое число от -32768 до 32767. - `int32` — 4 байта. Целое число от -2147483648 до 2147483647. - `int64` — 8 байт. Целое число от –9 223 372 036 854 775 808 до 9 223 372 036 854 775 807. - `uint8` — 1 байт. Целое число от 0 до 255. - `uint16` — 2 байта. Целое число от 0 до 65535. - `uint32` — 4 байта. Целое число от 0 до 4294967295. - `uint64` — 8 байт. Целое число от 0 до 18 446 744 073 709 551 615. - `byte` — 1 байт. Синоним типа `uint8`, представляет целое число от 0 до 255. - `rune` — 4 байта. Синоним типа `int32`, представляет целое число от -2147483648 до 2147483647. - `int` — 4/8 байт. В зависимости о платформы соответствует либо `int32`, либо `int64`. - `uint` — 4/8 байт. В зависимости о платформы соответствует либо `uint32`, либо `uint64`. - `float32` — 4 байта. Число с плавающей точкой от -3.4e+38 до 3.4e+38. - `float64` — 8 байт. Число с плавающей точкой от -1.7e+308 до 1.7e+308. - `complex64` — 8 байт. Комплексное число, где вещественная и мнимая части представляют числа `float32`. - `complex128` — 16 байт. Комплексное число, где вещественная и мнимая части представляют числа `float64`. - `bool` — 1 байт. Логический тип или тип `bool` может иметь одно из двух значений: `true` (истина) или `false` (ложь). - `string` — строка, строки не изменяемы. - указатели. В списке выше перечислены встроенные типы языка Go. «Встроенные» означает такие, которые уже есть на уровне самого языка, встроенные в компилятор. Помимо встроенных типов данных, существуют составные типы, которые может определить сам программист, а также некоторые другие особенные типы, о которых мы поговорим позже в этом курсе. Переменные определяются с использованием следующего синтаксиса: ``` var <имя переменной> <тип переменной> ``` Например: ```go var i int ``` При объявлении переменной по умолчанию для всех численных переменных задается нулевое значение, для типа `bool` — `false`, для строки — пустая строка. Также допустимо короткое объявление переменной, с неявным типом, например: ```go var i = 5 ``` При таком объявлении компилятор сам определит тип переменной. Более короткая запись: ```go i := 5 ``` Последнее работает только внутри функций. В Go также используются указатели в стиле C. Например, чтобы объявить переменную типа указатель на `string`, нужно поставить перед словом `string` символ `*`. Чтобы взять адрес переменной, необходимо перед именем переменной поставить символ `&`, а чтобы разыменовать указатель и получить значение необходимо поставить `*`. Арифметика указателей отсутствует во избежание ошибок. Пример использования указателей: ```go {.example_for_playground .example_for_playground_001} var s string s = "Hello!" var p *string // переменная p типа указатель на string p = &s // взять адрес переменной s и присвоить в переменную p fmt.Println(*p) //получить значение строки по адресу p и вывести на экран ``` Допишите функцию `swap()`, которая принимает на вход два указателя типа `string`, и меняет местами значения соответствующих переменных. Программа должна вывести сообщение `Hello, gophers!`. {.task_text} ```go {.task_source #golang_chapter_0010_task_0010} package main import "fmt" func swap(p *string, p2 *string) { // ваш код здесь } func main() { var s string var s2 string s = ", gophers!" s2 = "Hello" swap(&s, &s2) fmt.Println(s + s2) } ``` Для обмена местами значений двух переменных между собой используйте третью переменную. {.task_hint} ``` golang {.task_answer} package main import "fmt" func swap(p *string, p2 *string) { var s = *p *p = *p2 *p2 = s } func main() { var s string var s2 string s = ", gophers!" s2 = "Hello" swap(&s, &s2) fmt.Println(s + s2) } ``` ## Резюме 1. Язык Go — компилируемый многопоточный язык программирования. 2. Четких указаний по структуре проекта на Go нет, однако существует популярный способ организовать его. 3. В языке Go существует 18 встроенных типов, не считая указателей. Переменные могут объявляться как с явным, так и с неявным типом. 4. В языке Go используются указатели в стиле C. Арифметика указателей отсутствует. 5. Каждая программа на языке Go состоит из множества файлов, объединяемых в так называемые пакеты. Один из таких пакетов — пакет `fmt`. Главный пакет называется `main`: также, как функция, определяющая точку входа в программу. Пакеты объединяются в модули.
Отправка...
Наша группа в telegram. Здесь можно задавать вопросы и общаться.
Задонатить. Если вам нравится курс, вы можете поддержать развитие площадки!