Ответ
В Go нет классических модификаторов доступа (таких как private
, public
, protected
в других языках), но сокрытие данных (инкапсуляция) реализуется через простые правила именования на уровне пакетов:
- Экспортируемые (публичные) идентификаторы: Идентификаторы (переменные, функции, типы, методы), начинающиеся с заглавной буквы, являются экспортируемыми. Это означает, что они доступны для использования из других пакетов.
- Неэкспортируемые (приватные) идентификаторы: Идентификаторы, начинающиеся с прописной буквы, не экспортируются. Они доступны только внутри того пакета, в котором они объявлены.
Это называется инкапсуляцией на уровне пакета.
Пример:
package bank // Пакет bank
import "fmt"
// Account - публичный тип (начинается с заглавной буквы).
// Его поля owner и balance являются приватными.
type Account struct {
owner string // приватное поле (не экспортируется)
balance int // приватное поле (не экспортируется)
}
// NewAccount - публичная функция-конструктор для создания нового Account.
// Это предпочтительный способ создания экземпляров, так как он позволяет
// контролировать инициализацию приватных полей.
func NewAccount(owner string, initialBalance int) *Account {
if !validateAmount(initialBalance) {
fmt.Println("Начальный баланс должен быть положительным.")
return nil
}
return &Account{owner: owner, balance: initialBalance}
}
// Deposit - публичный метод для внесения средств.
func (a *Account) Deposit(amount int) {
if validateAmount(amount) {
a.balance += amount
fmt.Printf("Внесено %d. Новый баланс: %dn", amount, a.balance)
} else {
fmt.Println("Сумма для внесения должна быть положительной.")
}
}
// Balance - публичный метод для получения текущего баланса.
func (a *Account) Balance() int {
return a.balance
}
// validateAmount - приватная функция (начинается с прописной буквы).
// Доступна только внутри пакета bank.
func validateAmount(amount int) bool {
return amount > 0
}
Использование из другого пакета (например, main
):
package main
import (
"fmt"
"your_module/bank" // Предполагается, что пакет bank находится в your_module
)
func main() {
// Создаем новый аккаунт через публичный конструктор
myAccount := bank.NewAccount("Alice", 100)
if myAccount == nil {
return
}
// Доступ к публичному методу Deposit
myAccount.Deposit(50)
// Доступ к публичному методу Balance
fmt.Printf("Текущий баланс: %dn", myAccount.Balance())
// Попытка прямого доступа к приватным полям вызовет ошибку компиляции:
// fmt.Println(myAccount.balance) // Ошибка: myAccount.balance не экспортируется
// bank.validateAmount(10) // Ошибка: bank.validateAmount не экспортируется
}
Таким образом, приватные поля и функции доступны только внутри своего пакета, а взаимодействие с ними извне возможно только через публичные методы и функции, что обеспечивает контроль над состоянием объектов и соблюдение принципов инкапсуляции.