Что такое пакеты в Go и как работает экспорт/импорт идентификаторов?

Ответ

Пакеты в Go — это основной способ организации и структурирования кода. Каждый каталог с одним или несколькими .go файлами, объявленными с одинаковым package именем, представляет собой один пакет.

Ключевые принципы работы пакетов:

  • Организация: Пакеты группируют связанный код, делая его переиспользуемым и поддерживаемым.
  • Пространство имён: Каждый пакет имеет своё пространство имён, что предотвращает конфликты имён.
  • main пакет: Специальный пакет с именем main и функцией main() является точкой входа для исполняемого файла.

Экспорт и импорт (правило видимости)

В Go видимость идентификаторов (переменных, констант, типов, функций) за пределами пакета определяется очень просто — по регистру первой буквы имени:

  • Экспортируемый (публичный): Идентификатор, начинающийся с заглавной буквы, доступен из других пакетов, которые импортируют данный пакет.
  • Неэкспортируемый (приватный): Идентификатор, начинающийся со строчной буквы, доступен только внутри своего пакета.

Пример:

// Файл: mymath/math.go
package mymath

// Pi - экспортируемая константа, т.к. начинается с заглавной 'P'
const Pi = 3.14159

// Add - экспортируемая функция
func Add(a, b int) int {
    return a + b
}

// internalSum - приватная функция, недоступна извне
func internalSum(a, b int) int {
    return a + b
}
// Файл: main.go
package main

import (
    "fmt"
    "your_module/mymath" // Импорт нашего пакета
)

func main() {
    // Используем экспортированные идентификаторы
    sum := mymath.Add(10, 5)
    fmt.Printf("Sum: %d, Pi: %fn", sum, mymath.Pi)

    // Попытка вызова приватной функции приведёт к ошибке компиляции:
    // mymath.internalSum(1, 2) // Error: cannot refer to unexported name mymath.internalSum
}

При сборке проекта Go кэширует скомпилированные пакеты, что значительно ускоряет последующие сборки.