Итоги — Обобщенная коллекция
Часть раздела Объектно-ориентированное программирование путешествия по GO на Coddy. Урок 72 из 107.
Задание
ЛегкоДавайте создадим generic структуру данных Queue, которая продемонстрирует всё, что вы узнали о generics в Go! В отличие от стека (LIFO), queue соблюдает порядок First-In-First-Out (FIFO): первый добавленный item удаляется первым.
Вы организуете свой код в двух файлах:
queue.go: Define свою generic коллекцию queue.Создайте generic структуру
Queue[T any], которая хранит items internally. Ваша queue должна поддерживать следующие операции:Enqueue(item T)— adds item в back queueDequeue() (T, bool)— удаляет и возвращает item из front queue вместе с boolean, указывающим на успешность операции (возвращает нулевое значение иfalse, если queue empty)Peek() (T, bool)— возвращает front item, не удаляя его (та же схема возврата, что и у Dequeue)Size() int— возвращает number items в queueIsEmpty() bool— возвращает true, если queue has no items
Также создайте constructor function
NewQueue[T any]() *Queue[T], которая возвращает pointer на initialized empty queue.main.go: Продемонстрируйте работу queue с разными типами на основе входных данных.Прочитайте indicator типа (
intилиstring), затем прочитайте ряд commands, которые нужно выполнить над queue. Каждая command находится в отдельной строке:enqueue [value]— Add value в queuedequeue— удаляет и выводит front item (выведитеempty, если queue empty)peek— выводит front item, не удаляя его (выведитеempty, если queue empty)size— выводит текущий size
Читайте commands, пока не получите
done.
Будут предоставлены следующие входные данные:
- Строка 1: Type indicator (
intилиstring) - Следующие строки: Commands до
done
Например, для следующих входных данных:
int
enqueue 10
enqueue 20
enqueue 30
peek
dequeue
size
dequeue
dequeue
dequeue
doneВаш вывод должен быть таким:
10
10
2
20
30
emptyА для следующих входных данных:
string
enqueue hello
enqueue world
size
peek
dequeue
peek
doneВаш вывод должен быть таким:
2
hello
hello
worldВаша queue должна работать одинаково для integer и string типов, демонстрируя, как одна generic реализация обрабатывает несколько concrete типов, сохраняя полную type safety.
Попробуйте сами
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Прочитать индикатор типа
scanner.Scan()
typeIndicator := scanner.Text()
if typeIndicator == "int" {
// TODO: Создать очередь целых чисел с помощью NewQueue[int]()
// Обработать команды для очереди целых чисел
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: Обработать команды: enqueue, dequeue, peek, size
// Для enqueue разобрать целочисленное значение из parts[1]
// Для dequeue/peek вывести "empty", если очередь пуста
_ = command
}
} else if typeIndicator == "string" {
// TODO: Создать очередь строк с помощью NewQueue[string]()
// Обработать команды для очереди строк
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: Обработать команды: enqueue, dequeue, peek, size
// Для enqueue использовать строковое значение из parts[1]
// Для dequeue/peek вывести "empty", если очередь пуста
_ = command
}
}
// Они здесь, чтобы избежать ошибок неиспользуемых импортов во время разработки
_ = strconv.Atoi
_ = fmt.Println
}
Все уроки раздела Объектно-ориентированное программирование
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