Функция new()
Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 22 из 107.
Go предоставляет встроенную функцию new(), которая выделяет память для типа и возвращает указатель на неё. Выделенная память инициализируется нулевым значением типа.
p := new(int) // выделяет память для int
fmt.Println(*p) // 0 (нулевое значение)
fmt.Println(p) // 0xc000018030 (адрес памяти)Функция new() принимает тип в качестве аргумента и возвращает указатель на только что выделенное нулевое значение этого типа. Это особенно полезно, когда вам нужен pointer, но у вас нет существующей переменной, на которую можно было бы сослаться.
Для структур new() создаёт указатель на структуру, у которой все поля установлены в нулевые значения.
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p.Name) // "" (пустая строка)
fmt.Println(p.Age) // 0Возможно, вы задаётесь вопросом, когда использовать new(), а когда оператор получения адреса &. Оба приведённых ниже подхода эквивалентны:
// Использование new()
p1 := new(Person)
// Использование оператора адреса с литералом
p2 := &Person{}Синтаксис &Person{} чаще используется на практике, поскольку позволяет одновременно инициализировать fields. Используйте new(), когда вам нужен экземпляр с нулевыми значениями и вы предпочитаете явную семантику выделения memory.
Задание
ЛегкоДавайте создадим менеджер конфигурации, который демонстрирует, как new() выделяет память и инициализирует структуры их нулевыми значениями. Вы увидите, чем этот подход отличается от использования оператора адреса с литералом структуры.
Вы организуете код в двух файлах:
config.go: Определите структуруServerConfigс полямиHost(string),Port(int),MaxConnections(int) иDebugMode(bool). Создайте две функции:NewServerConfig, которая используетnew()для выделения памяти подServerConfigи напрямую возвращает указатель (со всеми нулевыми значениями)ConfigureServer, которая принимает указатель*ServerConfig, а также строку host и целое число port, после чего устанавливает эти поля в config через указатель
Displayдля*ServerConfig, который возвращает форматированную строку со всеми значениями конфигурации.main.go: Считайте host и port из входных данных. Сначала создайте config с помощьюNewServerConfig()и выведите его, чтобы показать нулевые значения. Затем используйтеConfigureServer, чтобы установить host и port, и снова выведите config, чтобы показать обновлённые значения.
Будут предоставлены следующие входные данные:
- Строка 1: имя host (string)
- Строка 2: номер port (целое число)
Ваш метод Display должен возвращать строку в следующем точном формате:
Host: [Host]
Port: [Port]
MaxConnections: [MaxConnections]
DebugMode: [DebugMode]Выведите результат работы метода дважды: один раз до настройки (с нулевыми значениями), а второй раз после настройки (с обновлёнными host и port).
Например, если заданы localhost и 8080, результат должен быть следующим:
Host:
Port: 0
MaxConnections: 0
DebugMode: false
Host: localhost
Port: 8080
MaxConnections: 0
DebugMode: falseОбратите внимание, что первый вывод показывает все нулевые значения (empty строка, 0, 0, false), поскольку new() инициализирует всё нулевыми значениями. После вызова ConfigureServer изменяются только host и port, а остальные поля сохраняют свои нулевые значения.
Попробуйте сами
package main
import (
"fmt"
)
func main() {
// Читать ввод
var host string
var port int
fmt.Scanln(&host)
fmt.Scanln(&port)
// TODO: Создать конфигурацию с помощью NewServerConfig() и отобразить её
// Это покажет нулевые значения
// TODO: Использовать ConfigureServer для установки host и port
// TODO: Отобразить конфигурацию снова, чтобы показать обновлённые значения
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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