← Назад к вопросам

В чем разница между названиями структур, начинающихся с маленькой и с большой буквы?

1.0 Junior🔥 291 комментариев
#Основы Go

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между публичными и приватными структурами в Go

В языке Go идентификаторы (имена структур, функций, переменных, методов), начинающиеся с заглавной буквы, являются публичными (экспортируемыми), а начинающиеся со строчной буквы - приватными (неэкспортируемыми). Это фундаментальное правило системы видимости (access control) в Go.

Ключевые различия

Публичные структуры (с заглавной буквы):

  • Могут использоваться за пределами пакета, где они объявлены
  • Видны в документации (godoc)
  • Составляют публичное API вашего пакета
  • Пример: type User struct { ... }

Приватные структуры (со строчной буквы):

  • Доступны только внутри того же пакета
  • Скрыты от внешних потребителей
  • Используются для внутренней реализации
  • Пример: type internalConfig struct { ... }

Примеры кода

// package user
package user

// Public структура - экспортируется
type User struct {
    Name     string // Публичное поле
    Email    string // Публичное поле
    password string // Приватное поле (строчная буква)
}

// Private структура - не экспортируется
type userSettings struct {
    theme    string
    language string
}

// Public метод
func (u *User) GetName() string {
    return u.Name
}

// Private метод
func (u *User) validatePassword() bool {
    // реализация валидации
    return true
}
// package main (другой пакет)
package main

import "user"

func main() {
    // OK: User - публичная структура
    u := user.User{Name: "John", Email: "john@example.com"}
    
    // ОШИБКА: userSettings недоступна
    // s := user.userSettings{} // Компилятор выдаст ошибку
    
    // OK: GetName - публичный метод
    name := u.GetName()
    
    // ОШИБКА: validatePassword недоступен
    // isValid := u.validatePassword() // Компилятор выдаст ошибку
}

Практические аспекты использования

Когда использовать публичные структуры:

  • Когда структура является частью публичного API библиотеки или пакета
  • Когда нужно, чтобы другие пакеты создавали экземпляры этой структуры
  • Для DTO (Data Transfer Objects), которые передаются между слоями приложения
  • Для конфигурационных структур, которые должны настраиваться извне

Когда использовать приватные структуры:

  • Для внутренних вспомогательных структур
  • Для реализации паттернов (фабрики, билдеры)
  • Для инкапсуляции сложной внутренней логики
  • Когда нужно скрыть детали реализации

Важные нюансы

  1. Вложенные структуры наследуют правила видимости:
type Container struct {
    PublicField  string
    privateField string
    Inner        innerStruct // Доступен, так как поле публичное
}

type innerStruct struct { // Но сама структура приватная
    data string
}
  1. Методы следуют тем же правилам:
func (u *User) PublicMethod() {}   // Доступен извне
func (u *User) privateMethod() {}  // Только внутри пакета
  1. Теги структур не влияют на видимость, только на сериализацию:
type User struct {
    Name string `json:"name"`     // Публичное поле с тегом
    age  int    `json:"age"`      // Приватное поле - не сериализуется наружу
}

Идиоматические паттерны

Фабричные функции для приватных структур:

package cache

type cache struct { // приватная структура
    data map[string]interface{}
}

// Публичная фабричная функция
func NewCache() *cache {
    return &cache{
        data: make(map[string]interface{}),
    }
}

// Публичные методы для работы с приватной структурой
func (c *cache) Set(key string, value interface{}) {
    c.data[key] = value
}

Сокрытие реализации интерфейса:

package storage

type Storage interface {
    Save(data []byte) error
    Load() ([]byte, error)
}

type fileStorage struct { // приватная реализация
    path string
}

func NewStorage(path string) Storage {
    return &fileStorage{path: path}
}

Заключение

Система видимости через регистр первой буквы - это простой, но мощный механизм контроля доступа в Go. Она позволяет:

  • Четко разделять публичное API и внутреннюю реализацию
  • Создавать стабильные интерфейсы, скрывая изменчивые детали
  • Предотвращать неправильное использование структур
  • Улучшать инкапсуляцию и поддерживаемость кода

Этот подход отличается от модификаторов доступа в других языках (как public/private в Java или C#) своей простотой и единообразием, что способствует написанию чистого, понятного и безопасного кода.

В чем разница между названиями структур, начинающихся с маленькой и с большой буквы? | PrepBro