Home

Published

-

Go Battle concepts

img of Go Battle concepts

Content

  1. Arrays and Slices
  2. Length vs Capacity
  3. Struct vs Map
  4. Overloading vs Overriding

Arrays and Slices

ArraysSlices
Fixed at compile-timeDynamic, can grow and shrink
Includes size in typeDoes not include size in type
Rarely used in GoCommonly used in Go
Can waste memory if unused sizeMore efficient for variable data
Arrays - [...]int{} or [n]int{}[]int{}
Go Array exampleGo slice example
   // Array declaration
var numbers [5]int // Fixed size of 5 integers
grades := [3]int{98, 93, 87} // Initialize with values
matrix := [2][3]int{{1, 2, 3}, {4, 5, 6}} // Multi-dimensional array

// Slice declaration
var scores []int // Zero-value slice (nil)
names := []string{"Pranshu", "Hritik", "Amit"} // Create slice with values
numbers := make([]int, 5) // Create slice with length 5
numbers := make([]int, 5, 10) // Create slice with length 5, capacity 10

Slice declaration

1. From an Arrays

   var arr = [5]int{1, 2, 3, 4, 5}
var slice = arr[1:4] // Create a slice of arr from index 1 to 3.
fmt.Println(slice)   // Output: [2 3 4]

2. From make

   slice := make([]int, 3, 5) // Length 3, capacity 5.
fmt.Println(slice)        // Output: [0 0 0]

3. using slice literals

   slice := []int{10, 20, 30}
fmt.Println(slice) // Output: [10 20 30]

operations on Slices

  1. appending to a slice
   slice := []int{1, 2, 3}
slice = append(slice, 4, 5)
fmt.Println(slice) // Output: [1 2 3 4 5]
  1. Copying Slices
   source := []int{1, 2, 3}
dest := make([]int, len(source))
copy(dest, source)
fmt.Println(dest) // Output: [1 2 3]

more detail on arrays and slice

1. Arrays ([...]int{} or [n]int{}) have a fixed size.

  • You cannot add or remove elements after declaration.
  • You can only modify existing elements.

2. Slices ([]int{}) are dynamic.

  • You can append or modify elements.
  • Slices are more commonly used in Go for their flexibility.

Length vs Capacity

Length(len)Slice(cap)
Number of elements in the sliceMaximum number of elements the slice can grow to without reallocating memory
function - len()function - cap()
   // Create a slice with length 3 and capacity 5
numbers := make([]int, 3, 5)
fmt.Printf("Length: %d, Capacity: %d\n", len(numbers), cap(numbers))
// Output: Length: 3, Capacity: 5

// The slice has 3 zero-value elements
fmt.Println(numbers)
// Output: [0 0 0]

// Append will add elements without reallocation until capacity is reached
numbers = append(numbers, 4)
fmt.Printf("After append - Length: %d, Capacity: %d\n", len(numbers), cap(numbers))
// Output: Length: 4, Capacity: 5

// When we exceed capacity, Go will allocate a new array with larger capacity
numbers = append(numbers, 5, 6)
fmt.Printf("After exceeding capacity - Length: %d, Capacity: %d\n", len(numbers), cap(numbers))
// Output: Length: 6, Capacity: 10 (Go typically doubles the capacity)

Behavior When Appending

  • When appending in slice and when exceed capacity, Go automatically allocate a new array with larger capacity.
  • The new capacity is typically doubled, but this depends on the implementation.

Struct vs Map

FeatureStructMap (map[string]any) or map[string]Ty
Fixed schemaFeild Names and types are defined at compile timeKeys are dynamic, not type-safe
Type SafetyStrongly typedWeak typing (especially with map[string]any)
PerformanceFaster (Less overhead)Slower (dynamic, uses hashing)
Memory UsageMore efficientHigher due to map internals
ReadabilityMore self-documentingLess clear structure
Use CaseKnown Structure (eg. Person)Unknown/Dynamic structure (eg: JSON-like data)
  • Struct: Best for known data
  • Map: Best for dynamic data

Overloading vs Overriding

Overloading in Go

  • Overloading means defining multiple functions or methods with the same name but different paramenter types of counts.
  • Not supported in Go
  • Results in Comipler Error: “Add redeclared in this block”

Overriding in Go

  • Overriding is possible through interfaces and embedding.

1. Supported via Interface implementation

   type Speaker interface {
    Speak()
}

type Dog struct{}

func (d Dog) Speak() {
    fmt.Println("Woof")
}

type Cat struct{}

func (c Cat) Speak() {
    fmt.Println("Meow")
}

func MakeItSpeak(s Speaker) {
    s.Speak()
}

2. Supported via embedding (similar to subclassing):

   type Animal struct{}

func (a Animal) Speak() {
    fmt.Println("Some sound")
}

type Dog struct {
    Animal
}

func (d Dog) Speak() {
    fmt.Println("Woof")
}

func main() {
    var d Dog
    d.Speak()        // "Woof"
    d.Animal.Speak() // "Some sound"
}