Recap - Generic Collection
Part of the Object Oriented Programming section of Coddy's GO journey — lesson 72 of 107.
Challenge
EasyLet's build a generic Queue data structure that demonstrates everything you've learned about generics in Go! Unlike a stack (LIFO), a queue follows First-In-First-Out (FIFO) ordering—the first item added is the first one removed.
You'll organize your code across two files:
queue.go: Define your generic queue collection.Create a generic struct
Queue[T any]that stores items internally. Your queue should support these operations:Enqueue(item T)- adds an item to the back of the queueDequeue() (T, bool)- removes and returns the item from the front of the queue, along with a boolean indicating success (return the zero value andfalseif the queue is empty)Peek() (T, bool)- returns the front item without removing it (same return pattern as Dequeue)Size() int- returns the number of items in the queueIsEmpty() bool- returns true if the queue has no items
Also create a constructor function
NewQueue[T any]() *Queue[T]that returns a pointer to an initialized empty queue.main.go: Demonstrate your queue with different types based on input.Read a type indicator (
intorstring), then read a series of commands to perform on the queue. Each command is on its own line:enqueue [value]- add the value to the queuedequeue- remove and print the front item (printemptyif queue is empty)peek- print the front item without removing (printemptyif queue is empty)size- print the current size
Read commands until you receive
done.
The following inputs will be provided:
- Line 1: Type indicator (
intorstring) - Following lines: Commands until
done
For example, given:
int
enqueue 10
enqueue 20
enqueue 30
peek
dequeue
size
dequeue
dequeue
dequeue
doneYour output should be:
10
10
2
20
30
emptyAnd given:
string
enqueue hello
enqueue world
size
peek
dequeue
peek
doneYour output should be:
2
hello
hello
worldYour queue should work identically for both integer and string types, demonstrating how a single generic implementation handles multiple concrete types while maintaining full type safety.
Try it yourself
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Read the type indicator
scanner.Scan()
typeIndicator := scanner.Text()
if typeIndicator == "int" {
// TODO: Create an integer queue using NewQueue[int]()
// Process commands for integer queue
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: Handle commands: enqueue, dequeue, peek, size
// For enqueue, parse the integer value from parts[1]
// For dequeue/peek, print "empty" if queue is empty
_ = command
}
} else if typeIndicator == "string" {
// TODO: Create a string queue using NewQueue[string]()
// Process commands for string queue
for scanner.Scan() {
line := scanner.Text()
if line == "done" {
break
}
parts := strings.SplitN(line, " ", 2)
command := parts[0]
// TODO: Handle commands: enqueue, dequeue, peek, size
// For enqueue, use the string value from parts[1]
// For dequeue/peek, print "empty" if queue is empty
_ = command
}
}
// These are here to avoid unused import errors during development
_ = strconv.Atoi
_ = fmt.Println
}
All lessons in Object Oriented Programming
1Fundamentals of Go OOP
External FilesGo Workspace & ModulesPackages & ImportsExported vs Unexported NamesIntroduction to OOP in GoStructs as ClassesDefining Methods on StructsPointer vs Value ReceiversStruct InitializationConstructor FunctionsRecap - Simple Calculator4Interfaces
Introduction to InterfacesImplicit ImplementationInterface as ContractEmpty Interface (any)Type AssertionType SwitchInterface CompositionStringer & Error InterfacesRecap - Shape Calculator7Encapsulation
Exported vs Unexported FieldsPackage-Level EncapsulationGetter & Setter MethodsInformation Hiding in GoRecap - Student Records10Generics (Go 1.18+)
Introduction to GenericsType ParametersType ConstraintsGeneric StructsGeneric Methods WorkaroundRecap - Generic Collection2Types & Structs Deep Dive
Basic & Composite TypesCustom Type DefinitionsStruct TagsAnonymous StructsNested StructsZero Values & DefaultsRecap - Contact Book5Composition Over Inheritance
Why Go Has No InheritanceStruct Embedding BasicsMethod PromotionEmbedding Multiple StructsEmbedding vs AggregationShadowing Embedded MethodsRecap - Employee Hierarchy8Error Handling & OOP
The error InterfaceCustom Error TypesError Wrapping (fmt.Errorf)Sentinel Errorserrors.Is() and errors.As()Panic, Defer, and RecoverRecap - File Parser3Pointers & Memory
Pointer Basics in GoPointers to StructsPass by Value vs ReferenceThe new() FunctionGarbage Collection in GoRecap - Linked List Builder6Polymorphism in Go
Polymorphism via InterfacesDuck Typing in GoInterface Satisfaction RulesPolymorphic CollectionsDependency InjectionRecap - Payment Processor9Concurrency & OOP
Goroutines BasicsChannels & CommunicationBuffered vs Unbuffered ChanSelect Statementsync.Mutex & sync.RWMutexsync.WaitGroupThread-Safe Struct DesignRecap - Worker Pool