Здравствуйте! В прошлом уроке мы с вами освоили базовый рабочий цикл: создали Go-модуль и запустили минимальную программу. Мы намеренно не вникали в код, сосредоточившись на инструментах. Сегодня мы сделаем следующий шаг и разберёмся в структуре этой программы.
Вы уже имеете богатый опыт работы с модульной системой в JavaScript/TypeScript, где import и export являются ключевыми элементами организации кода. В Go есть похожие, но концептуально иные механизмы. Этот урок посвящён трём фундаментальным конструкциям, которые вы увидите в начале любого исполняемого Go-файла: package, import и func main. Поняв их роль, вы получите ключ к архитектуре любой Go-программы.
Что такое пакет (package)?
В Go основной единицей организации и переиспользования кода является пакет. В отличие от экосистемы Node.js, где каждый файл часто является отдельным модулем, в Go пакет — это совокупность всех .go файлов, находящихся в одной директории. Все эти файлы должны принадлежать одному и тому же пакету, что объявляется в самой первой строке каждого файла.

Прочитайте краткое введение в концепцию пакетов.
Go packages, Go modules and init functions tutorial | golangbot.com
В этом разделе автор объясняет, для чего нужны пакеты в Go.
Прочтите раздел "What are packages and why are they used?". Обратите внимание на ключевую идею: пакеты служат для организации, переиспользования и улучшения читаемости кода.
Важно усвоить: все переменные, функции и типы, объявленные в одном файле пакета, напрямую доступны во всех остальных файлах этого же пакета, без необходимости каких-либо импортов. Это как если бы все JS-файлы в одной папке были "склеены" в один большой файл перед исполнением.
Посмотрите, как это объясняется и демонстрируется в видео.
Golang imports tutorial: how to import Golang local package | Golang tutorial
Автор видео наглядно показывает, что все .go файлы в одной директории составляют единый пакет.
Смотрите фрагмент с этого момента. Обратите внимание на ошибку, которая возникает при попытке объявить разные пакеты в одной директории, и на то, как переменная из одного файла становится доступна в другом после исправления.
package main и func main: Точка входа в программу
Среди всех пакетов есть один особенный — main. Объявление package main сообщает компилятору, что данный пакет является исполняемым. Это значит, что его можно скомпилировать в самостоятельную программу (исполняемый файл), а не в библиотеку для использования в других пакетах.
Любой исполняемый пакет должен содержать функцию main(). Эта функция без аргументов и без возвращаемых значений является точкой входа — именно с неё начинается выполнение программы.

В следующем видео автор чётко разделяет пакеты на два типа: исполняемые (main) и неисполняемые (библиотечные).
Это видео объясняет разницу между двумя типами пакетов в Go.
Посмотрите два коротких фрагмента. Первый объясняет разницу между исполняемыми (main) и библиотечными пакетами. Второй демонстрирует на примере, что запустить можно только main пакет, содержащий функцию main.
Давайте закрепим это, прочитав раздел из статьи, который детально описывает роль пакета main.
An introduction to Packages, Imports and Modules in Go
Здесь подробно раскрывается особая роль package main и функции main().
Прочтите раздел "The main package". Заметьте, что по соглашению, функцию main() принято размещать в файле main.go.
import: Подключение внешнего кода
Как и в TypeScript, для использования функциональности из других пакетов используется инструкция import. Она позволяет вашему коду обращаться к экспортируемым элементам (функциям, переменным, типам) из стандартной библиотеки Go или других пакетов вашего проекта.
Ключевое отличие от JavaScript:
- Импортируется пакет, а не файл. Вы указываете путь к пакету (например,
"fmt"или"math/rand"). - Именем пакета становится префикс для доступа. После
import "fmt"вы используетеfmt.Println(). Имяfmtздесь — это идентификатор пакета, а не переменная, которую можно переименовать по желанию, как вimport * as myFmt from 'fmt'.
В Go существует строгое правило: импортировать пакет, но не использовать его, является ошибкой компиляции. Это заставляет поддерживать чистоту и порядок в зависимостях.
Посмотрите, как работает импорт локального пакета из поддиректории. Этот пример хорошо иллюстрирует, как путь импорта строится из имени модуля (из go.mod) и пути к директории пакета.
Golang imports tutorial: how to import Golang local package | Golang tutorial
В этом фрагменте автор создает пакет в поддиректории и импортирует его в main.
Смотрите раздел с этого момента. Обратите особое внимание на то, как конструируется путь для импорта (news.com/events/articles) и как для доступа к переменной используется имя пакета (art.Article), а не имя директории (articles).
Теперь прочитаем об импортах в статье, чтобы систематизировать знания.
An introduction to Packages, Imports and Modules in Go
Эти разделы описывают механику импорта и строгие правила компилятора.
Сначала прочтите раздел "Importing and using standard library packages", чтобы понять, как формируется путь импорта и как имя пакета используется для доступа. Затем ознакомьтесь с разделом "Unused and missing imports", чтобы понять, почему Go выдает ошибку при наличии неиспользуемых импортов.
Экспортируемые имена
Вы могли заметить, что в примерах функции и переменные, которые используются из других пакетов, начинаются с заглавной буквы (fmt.Println, rand.Intn, art.Article). Это не случайно.
В Go правило видимости очень простое: если имя (переменной, типа, функции) начинается с заглавной буквы, оно экспортируется и доступно из других пакетов. Если с маленькой — оно приватно для текущего пакета. Мы подробно вернемся к этому в одном из следующих модулей, но это важный аспект, связанный с работой import.
Прочитайте короткое объяснение.
Go packages, Go modules and init functions tutorial | golangbot.com
Этот раздел объясняет правило экспорта имен в Go.
Прочтите раздел "Exported Names".
Заключение
В этом уроке мы разобрали три кита, на которых держится структура исполняемой Go-программы:
package: Объявляет принадлежность файла к пакету. Все файлы в одной директории составляют один пакет.package main: Особый тип пакета, который компилируется в исполняемый файл.func main(): Точка входа в программу, которая должна находиться в пакетеmain.import: Подключает другие пакеты, позволяя использовать их экспортируемую (начинающуюся с заглавной буквы) функциональность.
Теперь вы понимаете, что означают первые строки кода в файле main.go, который мы создали в прошлом уроке. Вы знаете, как программа находит свою точку входа и как она подключает внешние зависимости.
В следующем уроке мы, наконец, заглянем внутрь функции main и начнем работать с данными. Мы научимся объявлять переменные и константы, разберемся с типами данных и их нулевыми значениями.