Table of Contents
Stack using Array
Golang code for Stack using Array
package main
import (
"errors"
"fmt"
)
type stack struct {
arr [10]int
top int
}
func (s *stack) push(item int) error {
if s.top < len(s.arr)-1 {
s.top = s.top + 1
s.arr[s.top] = item
return nil
}
return errors.New("Stack capacity is full")
}
func (s *stack) pop() (int, error) {
if s.top > -1 {
item := s.arr[s.top]
s.top = s.top - 1
return item, nil
}
return -1, errors.New("Stack is empty")
}
// Renamed function to avoid confusion with field "top"
func (s *stack) topElement() (int, error) {
if s.top > -1 {
return s.arr[s.top], nil
}
return -1, errors.New("Stack is empty")
}
func (s *stack) size() int {
return s.top + 1
}
func main() {
s := stack{
// arr: [10]int{}, // No need to initialize an array like this
top: -1,
}
err := s.push(10)
if err ! = nil {
fmt.Println("Error occurred in push operation:", err.Error())
}
err = s.push(20)
if err ! = nil {
fmt.Println("Error occurred in push operation:", err.Error())
}
err = s.push(30)
if err ! = nil {
fmt.Println("Error occurred in push operation:", err.Error())
}
item, err := s.topElement()
if err ! = nil {
fmt.Println("Error occurred in finding top operation:", err.Error())
} else {
fmt.Printf("Top=%d\n", item)
}
fmt.Printf("Size of stack=%d\n", s.size())
item, err = s.pop()
if err ! = nil {
fmt.Println("Error occurred in pop operation:", err.Error())
} else {
fmt.Printf("Popped Top=%d\n", item)
}
}
Variations of usage of type struct
When to Use Value Receiver (Pass-by-Value)
You can and should use pass-by-value in certain cases, especially when:
- No modification is needed:
- If your method only reads the data from the struct without changing it, using a value receiver is fine.
- Example: Calculating or printing some information based on the struct’s fields.
- If your method only reads the data from the struct without changing it, using a value receiver is fine.
func (s stack) isEmpty() bool {
return s.top == -1
}
- The struct is small:
- If the struct is small, copying it is not costly, and passing it by value may be more efficient.
- Small structs like
struct { x, y int }
are cheap to copy because they only take a small amount of memory.
- Small structs like
- If the struct is small, copying it is not costly, and passing it by value may be more efficient.
type Point struct {
x, y int
}
func (p Point) distance() int {
return p.x * p.x + p.y * p.y
}
- Immutable operations: When you explicitly want to create a copy of the struct and ensure the original doesn’t get modified, passing by value guarantees this immutability.
- Example: When you want to perform operations on a copy of the struct, but you don’t want to modify the original struct.
When to Use Pointer Receiver (Pass-by-Pointer)
You should use pass-by-pointer when:
You need to modify the original struct: If the method changes the state of the struct (like modifying fields), you should use a pointer receiver to ensure the original instance is modified.
func (s *stack) push(item int) {
s.top++
s.arr[s.top] = item
}
The struct is large: If the struct contains a lot of fields or large data (e.g., large arrays, maps, or slices), copying the entire struct is inefficient. In such cases, passing a pointer avoids unnecessary copying and improves performance.
type LargeData struct {
data [10000]int
}
func (l *LargeData) process() {
// Modify or process data
}
Avoiding excessive copies: If a method is called frequently or the struct is used in multiple places, it may be better to use pointer receivers to avoid making too many copies and save memory.
General Guidelines
Pass-by-value (value receiver)
- Use when the struct is small and you don’t need to modify it.
- Ideal for read-only methods or when immutability is desired.
- Efficient for small structs or when copying is cheaper than dereferencing a pointer.
Pass-by-pointer (pointer receiver)
- Use when you need to modify the struct.
- Use for large structs to avoid unnecessary copying.
- Ensures that the method works on the original instance, not a copy.
Example: When to Use Each
// Value receiver: does not modify the original stack, just reads it.
func (s stack) isEmpty() bool {
return s.top == -1
}
// Pointer receiver: modifies the original stack.
func (s *stack) push(item int) {
if s.top < len(s.arr)-1 {
s.top++
s.arr[s.top] = item
}
}
Conclusion
- You don’t need to always use pass-by-pointer for structs.
- Use pass-by-value when you only need to read data and the struct is small.
- Use pass-by-pointer when you need to modify the struct or avoid unnecessary copying for large structs.
Visit https: https://codeandalgo.com for more such contents
Leave a Reply