Нулевые значения и значения по умолчанию
Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 17 из 107.
В Go каждая переменная имеет нулевое значение: значение по умолчанию, присваиваемое при объявлении переменной без явной инициализации. Понимание нулевых значений необходимо для работы со структурами, поскольку неинициализированные поля автоматически получают эти значения по умолчанию.
У каждого типа есть собственное нулевое значение:
| Тип | Нулевое значение |
|---|---|
| int, float64 | 0 |
| string | "" (пустая строка) |
| bool | false |
| pointer, slice, map | nil |
Когда вы создаёте struct, любое поле, которому вы явно не присвоили значение, получает своё нулевое значение.
type User struct {
Name string
Age int
Active bool
}
func main() {
var u User
fmt.Println(u.Name) // "" (пустая строка)
fmt.Println(u.Age) // 0
fmt.Println(u.Active) // false
}Это также относится к partial initialization. Only указанные вами fields получают пользовательские значения.
u := User{Name: "Alice"}
fmt.Println(u.Age) // 0
fmt.Println(u.Active) // false
Нулевые значения делают структуры сразу готовыми к использованию без явной initialization. Однако будьте осторожны с ссылочными типами, такими как срезы и map. Их нулевое значение — nil, что может привести к панике во время выполнения, если попытаться использовать их без инициализации.
Задание
ЛегкоДавайте создадим систему профиля игрока, которая демонстрирует, как работают нулевые значения в Go. Вы создадите игровой профиль, в котором некоторые поля заданы явно, а другие используют их стандартные нулевые значения.
Вы организуете код в двух файлах:
player.go: Define структуруPlayerсо следующими полями:Username(string),Level(int),Score(int),IsPremium(bool) иGuildName(string). Также создайте methodDisplayProfile, который returns formatted string со всей информацией об игроке.main.go: Read имя пользователя из input и создайте Player, используя только partial initialization: задайте только полеUsername. Затем отобразите полный профиль, чтобы увидеть, как Go заполняет не заданные поля их нулевыми значениями.
Будет предоставлен following input:
- Строка 1: имя пользователя игрока
Ваш method DisplayProfile should return string в точно таком формате:
Username: [Username]
Level: [Level]
Score: [Score]
Premium: [IsPremium]
Guild: [GuildName]Например, если имя пользователя — ShadowKnight, результат должен содержать имя пользователя вместе со всеми нулевыми значениями для неинициализированных полей:
Username: ShadowKnight
Level: 0
Score: 0
Premium: false
Guild: Обратите внимание, что поле Guild после двоеточия ничего не содержит: это нулевое значение empty string. Это задание поможет вам точно увидеть, что Go присваивает каждому типу, если вы не указываете явное значение.
Попробуйте сами
package main
import (
"fmt"
)
func main() {
// Прочитать имя пользователя из ввода
var username string
fmt.Scanln(&username)
// TODO: Создать Player с помощью частичной инициализации
// Установить только поле Username, пусть остальные поля используют нулевые значения
// TODO: Отобразить профиль игрока с помощью метода DisplayProfile
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП в Go
Внешние файлыРабочее пространство и модули GoПакеты и импортыЭкспортируемые и неэкспортируемые именаВведение в ООП в GoСтруктуры как классыОпределение методов структурПолучатели-указатели и получатели-значенияИнициализация структурФункции-конструкторыИтоги — Простой калькулятор4Интерфейсы
Введение в интерфейсыНеявная реализацияИнтерфейс как контрактПустой интерфейс (any)Утверждение типаПереключатель типовКомпозиция интерфейсовИнтерфейсы Stringer и ErrorПовторение: Калькулятор фигур7Инкапсуляция
Экспортируемые и неэкспортируемые поляИнкапсуляция на уровне пакетовГеттеры и сеттерыСокрытие информации в GoИтоги — Записи о студентах10Обобщения (Generics) (Go 1.18+)
Введение в GenericsПараметры типовОграничения типовОбобщенные структурыОбходной путь для обобщенных методовИтоги — Обобщенная коллекция13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн Abstract FactoryПаттерн ObserverПаттерн Strategy2Глубокое погружение в типы и структуры
Базовые и составные типыОпределение пользовательских типовТеги структурАнонимные структурыВложенные структурыНулевые значения и значения по умолчаниюПовторение — Контактная книга5Композиция вместо наследования
Почему в Go нет наследованияОсновы встраивания структурПродвижение методовВстраивание нескольких структурВстраивание против агрегацииЗатенение встроенных методовИтоги — Иерархия сотрудников8Обработка ошибок и ООП
Интерфейс errorПользовательские типы ошибокОбертывание ошибок (fmt.Errorf)Sentinel-ошибкиerrors.Is() и errors.As()Panic, Defer и RecoverИтоги — Парсер файлов11Стандартная библиотека и ООП
io.Reader и io.Writersort.InterfaceИнтерфейс fmt.Stringerencoding/json со структурамиИнтерфейс http.HandlerПовторение: модели REST API14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикMiddleware как Декоратор3Указатели и память
Основы указателей в GoУказатели на структурыПередача по значению и по ссылкеФункция new()Сборка мусора в GoПовторение: Конструктор связного списка6Полиморфизм в Go
Полиморфизм через интерфейсыУтиная типизация в GoПравила реализации интерфейсовПолиморфные коллекцииВнедрение зависимостейИтоги — Обработчик платежей9Конкурентность и ООП
Основы горутинКаналы и взаимодействиеБуферизованные и небуферизованные каналыОператор selectsync.Mutex и sync.RWMutexsync.WaitGroupПроектирование потокобезопасных структурПовторение — Worker PoolПотренируйтесь самостоятельно: Онлайн-компилятор Go