Published
-
Go Battle concepts

Content
Arrays and Slices
Arrays | Slices |
---|---|
Fixed at compile-time | Dynamic, can grow and shrink |
Includes size in type | Does not include size in type |
Rarely used in Go | Commonly used in Go |
Can waste memory if unused size | More efficient for variable data |
Arrays - [...]int{} or [n]int{} | []int{} |
Go Array example | Go 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
- appending to a slice
slice := []int{1, 2, 3}
slice = append(slice, 4, 5)
fmt.Println(slice) // Output: [1 2 3 4 5]
- 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 slice | Maximum 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
Feature | Struct | Map (map[string]any) or map[string]Ty |
---|---|---|
Fixed schema | Feild Names and types are defined at compile time | Keys are dynamic, not type-safe |
Type Safety | Strongly typed | Weak typing (especially with map[string]any) |
Performance | Faster (Less overhead) | Slower (dynamic, uses hashing) |
Memory Usage | More efficient | Higher due to map internals |
Readability | More self-documenting | Less clear structure |
Use Case | Known 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"
}