Ответ
В Go управление видимостью (инкапсуляция) реализовано на уровне пакетов и определяется регистром первой буквы идентификатора (имени переменной, константы, типа, функции, поля структуры и т.д.).
- Экспортируемый (публичный) идентификатор начинается с заглавной буквы. Он доступен из любого другого пакета, который импортирует пакет, где он определен.
- Неэкспортируемый (приватный) идентификатор начинается со строчной буквы. Он доступен только внутри того же пакета, в котором определен.
Пример
Допустим, у нас есть пакет calculator
:
// file: calculator/calculator.go
package calculator
// pi - неэкспортируемая константа, доступна только внутри пакета calculator
const pi = 3.14159
// Add - экспортируемая функция, доступна из других пакетов
func Add(a, b int) int {
return a + b
}
// subtract - неэкспортируемая функция
func subtract(a, b int) int {
return a - b
}
Теперь используем его из пакета main
:
// file: main.go
package main
import (
"fmt"
"myproject/calculator"
)
func main() {
// Корректный вызов экспортируемой функции
sum := calculator.Add(5, 3)
fmt.Println("Sum:", sum) // Output: Sum: 8
// Ошибка компиляции: попытка доступа к неэкспортируемому идентификатору
// diff := calculator.subtract(5, 3) // cannot refer to unexported name calculator.subtract
// fmt.Println(calculator.pi) // cannot refer to unexported name calculator.pi
}
Ключевые моменты
- Область видимости — пакет: В Go нет модификаторов
public
,private
илиprotected
, как в других языках. Видимость определяется исключительно на уровне пакетов. - Применяется ко всему: Это правило касается переменных, констант, функций, типов (структур, интерфейсов) и их полей/методов.
- Инкапсуляция: Это основной механизм инкапсуляции в Go, позволяющий скрыть детали реализации пакета и предоставить наружу только стабильный и продуманный API.