Будь вы опытным разработчиком Golang или только начинаете работать с Golang, вы, вероятно, часто слышали слова «пакет» (package) и «модуль» (module) или, по крайней мере, сталкивались с ними в каком-нибудь материале.
Поначалу мне было сложно разобраться с этими двумя понятиями, но не в том, каковы их определения, а в том, что они означают для экосистемы, в которой вы будете работать, создавая/прописывая программы на Golang.
В этой статье мы поговорим о том, что такое пакеты в языке программирования Go (Golang) и о нескольких важных концепциях, связанных с ними.
Пакеты — Packages
Пакет — это файл или группа файлов с пространством имен и некоторым кодом или связанным с ним кодом. Это означает, что пакет может находиться в одном файле, например math.go
, или в нескольких файлах, таких как add.go
, subctract.go
, multiply.go
, то есть во многих файлах или в одном файле, например, с именем package math
.
Пакет будет иметь окружающий каталог, например:
Содержимое файла math.go может выглядеть примерно так:
Если мы решили разбить этот математический пакет на несколько файлов, мы можем создать три файла add.go, subctract.go, multiply.go со следующим содержимым…
add.go из пакета math
:
subtract.go из пакета math
:
multiply.go из пакета math
:
Взглянув на все три результирующих файла, вы, возможно, уже заметили общий знаменатель — все они используют одно и то же пространство имен пакета math
. Конечно, вы, скорее всего, никогда не встретите человека, делающего что-то подобное, если только он не разбивает очень большие файлы на несколько файлов. Понимание концепции общего пространства имен очень важно для того, о чем мы будем говорить дальше.
Экспортируемые и локальные функции/методы
Идея написания пакетов в Golang заключается в создании модульных фрагментов кода, которыми можно делиться в своих проектах или с другими разработчиками для использования в их собственных проектах. Так держать, Golang! Мне нравится твоя щедрая натура.
Для того чтобы это произошло, и чтобы это произошло безопасно, мы можем захотеть раскрыть некоторые части нашего кода как внешние API, которые будут использоваться, а также сохранить некоторые аспекты пакета более скрытыми и не такими доступными. Некоторые языки предоставляют такие конструкции, как public
, private
, protected
, чтобы помочь в этом, но в Golang концепции публичных (public
) и частных (private
) API вытекают из того, как мы называем наши функции, методы и свойства. Давайте рассмотрим пример.
Если посмотреть на иллюстрацию выше, у нас есть две функции, названные одинаково, с одним отличием: одна из них — multiply
со строчной буквы, а другая начинается с прописной Multiply
, и это тонкое различие является отличием между локальной и экспортируемой функцией в Golang. Вы можете гадать, кто из них кто Вы можете быть правы, судя по их структуре, но, тем не менее, в Golang, когда вы называете что-то полностью строчными буквами, это локализовано и не может быть доступно вне этого пакета (помните, что такое пакет? посмотрите еще раз?). С другой стороны, все, что начинается с заглавной буквы, может быть доступно как внутри, так и вне пакета, в котором оно было определено/объявлено.
Так что если мы опубликовали наш пакет сегодня (мы рассмотрим публикацию пакетов в ближайшее время), мы можем импортировать этот математический пакет и получить доступ к Multiply
, но попытка получить доступ к multiply
определенно вызовет ошибку!
В то время как мы можем получить доступ к multiply
в том же пространстве имен, даже в другом файле!
Эти концепции могут стать разницей между красиво и творчески структурированным кодом на Go и беспорядочными программами. Следует отметить, что math
здесь использовалось как иллюстративное имя пакета, НЕ ИСПОЛЬЗУЙТЕ ЕГО в реальных или игровых приложениях, так как в Golang уже есть встроенный математический пакет, и это наверняка приведет к нежелательному поведению (но вы можете попробовать, если вам интересно).
Резюме
- Пакет можно представить как файл, имеющий имя (вверху) и содержащий некоторый связанный код
- Это также может быть группа файлов с одним и тем же пространством имен
package
, содержащих связанный код - Не разбивайте преждевременно пакеты на несколько файлов, если только это не крайне необходимо, например, если файлом трудно управлять, или если у вас есть динамически генерируемый код во время выполнения (мы обсудим генерацию кода в ближайшее время) и т. д. Кроме того, даже если вы разделите пакеты на разные файлы, они должны находиться в одной директории, иначе вы испортите импорт в дальнейшем.
- В Golang понятия приватных и публичных функций, методов и типов подразумеваются в зависимости от того, как вы называете эти конструкции. Если они начинаются с заглавной буквы, то к ним могут обращаться пакеты, не входящие в текущий пакет, если со строчной буквы, то они становятся «приватными» (
private
) и недоступными/неприкосновенными за пределами текущего пакета.
Вот и все! Поехали, поехали, поехали Вы узнали немного Golang сегодня, спасибо вам большое, что следите за нами! В моей следующей статье мы рассмотрим модули и то, как они связаны с концепцией пакетов, до скорой встречи.