Implementing a Stack From Scratch

Why I Ended Up Implementing a Stack From Scratch in Go

Recently, during an interview, I was asked a standard question:

Validate a string of parentheses.

I solved it using stack.
But then the interviewer followed up with something unexpecte…


This content originally appeared on DEV Community and was authored by Abhishek

Why I Ended Up Implementing a Stack From Scratch in Go

Recently, during an interview, I was asked a standard question:

Validate a string of parentheses.

I solved it using stack.
But then the interviewer followed up with something unexpected:

“How would you implement a stack from scratch?”

And yeah… my brain froze.

After that, I decided to sit down, revise the fundamentals, and actually build a stack from scratch in Go.

What Exactly Is a Stack?

A stack is one of the simplest data structures.
It follows a very straightforward rule:

LIFO - Last In, First Out

A good analogy is a stack of plates:

  • You place plates on top (Push)
  • You remove plates from the top (Pop)
  • You never access items from the middle or bottom

The most recently added item is always the first one removed.

Core Operations of a Stack

A stack supports four basic operations:

Push - Add an item to the top
Pop - Remove and return the top item
Peek - Return the top item without removing it
IsEmpty - Check whether the stack contains any elements

These simple operations form the basis of many algorithms.

So here is the implementation.

Stack Implementation in Go (Using Generics)

package main

import "fmt"

func main() {
    var st Stack[int]
    st.Push(10)
    fmt.Println(st.Pop())
    fmt.Println(st.Peek())
    fmt.Println(st.IsEmpty())
    st.Push(71)
    fmt.Println(st.IsEmpty())
}

// stack
type Stack[T any] struct {
    data []T
}

// Push
func (s *Stack[T]) Push(value T) {
    s.data = append(s.data, value)
}

// Pop
func (s *Stack[T]) Pop() (T, bool) {
    var zero T
    if len(s.data) == 0 {
        return zero, false
    }
    value := s.data[len(s.data)-1]
    s.data = s.data[:len(s.data)-1]
    return value, true
}

// Peek
func (s *Stack[T]) Peek() (T, bool) {
    var zero T
    if len(s.data) == 0 {
        return zero, false
    }
    return s.data[len(s.data)-1], true
}

// IsEmpty
func (s *Stack[T]) IsEmpty() bool {
    return len(s.data) == 0
}
type Stack[T any] struct {
    data []T
}

What This Means

  • Stack is a generic type.
  • T represents any type: int, string, rune, struct, etc.
  • Internally, values are stored in a slice ([]T).

Slices naturally fit stack behavior because:

  • append() adds an element to the end (Push)
  • slicing ([:len-1]) removes the last element efficiently (Pop)

1. Push - Add an Item to the Top

func (s *Stack[T]) Push(value T) {
    s.data = append(s.data, value)
}

Push appends the element to the end of the slice, which represents the top of the stack.

Using a pointer receiver (*Stack[T]) ensures the original stack is modified.

2. Pop - Remove and Return the Top Element

func (s *Stack[T]) Pop() (T, bool) {
    var zero T
    if len(s.data) == 0 {
        return zero, false
    }

    value := s.data[len(s.data)-1]
    s.data = s.data[:len(s.data)-1]
    return value, true
}
  • If the stack is empty, Pop returns (zero value, false)
  • Otherwise, it returns the last element and removes it using slicing

zero is the default value of type T (0 for int, "" for string, false for bool, etc.)

3. Peek - View the Top Element Without Removing It

func (s *Stack[T]) Peek() (T, bool) {
    var zero T
    if len(s.data) == 0 {
        return zero, false
    }
    return s.data[len(s.data)-1], true
}

Peek returns the top element but leaves the stack unchanged.

4. IsEmpty - Check Whether the Stack Is Empty

func (s *Stack[T]) IsEmpty() bool {
    return len(s.data) == 0
}

A simple check based on slice length.

Example Usage

var st Stack[int]

st.Push(10)
fmt.Println(st.Pop())      // (10, true)
fmt.Println(st.Peek())     // (0, false)
fmt.Println(st.IsEmpty())  // true

st.Push(71)
fmt.Println(st.IsEmpty())  // false

Summary

This implementation:

  • Uses Go generics
  • Works for any type
  • Is clean, efficient, and easy to understand
  • Follows true LIFO behavior
  • Demonstrates how a stack is built internally

This is a complete, from-scratch stack implementation written in Go using generics.


This content originally appeared on DEV Community and was authored by Abhishek


Print Share Comment Cite Upload Translate Updates
APA

Abhishek | Sciencx (2025-11-16T05:01:20+00:00) Implementing a Stack From Scratch. Retrieved from https://www.scien.cx/2025/11/16/implementing-a-stack-from-scratch/

MLA
" » Implementing a Stack From Scratch." Abhishek | Sciencx - Sunday November 16, 2025, https://www.scien.cx/2025/11/16/implementing-a-stack-from-scratch/
HARVARD
Abhishek | Sciencx Sunday November 16, 2025 » Implementing a Stack From Scratch., viewed ,<https://www.scien.cx/2025/11/16/implementing-a-stack-from-scratch/>
VANCOUVER
Abhishek | Sciencx - » Implementing a Stack From Scratch. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/11/16/implementing-a-stack-from-scratch/
CHICAGO
" » Implementing a Stack From Scratch." Abhishek | Sciencx - Accessed . https://www.scien.cx/2025/11/16/implementing-a-stack-from-scratch/
IEEE
" » Implementing a Stack From Scratch." Abhishek | Sciencx [Online]. Available: https://www.scien.cx/2025/11/16/implementing-a-stack-from-scratch/. [Accessed: ]
rf:citation
» Implementing a Stack From Scratch | Abhishek | Sciencx | https://www.scien.cx/2025/11/16/implementing-a-stack-from-scratch/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.