Ответ
В Go нет ключевых слов public
, private
или protected
, как в других языках. Инкапсуляция и управление видимостью реализуются на уровне пакетов с помощью простого правила:
Имя, начинающееся с заглавной буквы, является экспортируемым (публичным). Имя, начинающееся со строчной буквы, — неэкспортируемым (приватным для пакета).
Существует два основных способа скрыть детали реализации:
-
Неэкспортируемые идентификаторы (уровень пакета)
Любой идентификатор (переменная, константа, тип, функция), имя которого начинается с маленькой буквы, доступен только внутри того пакета, в котором он определен. Это основной механизм сокрытия данных в Go.
// В пакете 'counter' // secretCounter не виден за пределами пакета 'counter' var secretCounter int // Increment является экспортируемой функцией func Increment() { secretCounter++ }
-
Использование интерфейсов для сокрытия реализации
Этот подход позволяет полностью скрыть конкретную структуру, предоставляя наружу только интерфейс. Пользователь пакета работает с поведением (методами интерфейса), а не с конкретными данными.
// В пакете 'database' // DB - публичный интерфейс type DB interface { Query(string) (string, error) } // pgDB - неэкспортируемая структура, конкретная реализация type pgDB struct { connection string // ... другие приватные поля } func (db *pgDB) Query(q string) (string, error) { // ... логика запроса к PostgreSQL return "result", nil } // New - публичная "фабрика", возвращает публичный интерфейс, // скрывая приватную реализацию. func New(connStr string) DB { return &pgDB{connection: connStr} }
В этом примере код из другого пакета может создать объект
pgDB
черезdatabase.New()
, но получит его в виде переменной типаdatabase.DB
. Он не будет иметь доступа к полям структурыpgDB
и сможет вызывать только методы, определенные в интерфейсеDB
.