Mastering Go Slices: Building Fundamental Operations
Go slices are a powerful and flexible data structure, serving as dynamic views into underlying arrays. Understanding how to manipulate them is crucial for efficient Go programming. This challenge will guide you through implementing common slice operations from scratch, deepening your comprehension of their mechanics.
Problem Description
Your task is to implement several fundamental slice operations in Go. You will create functions that mimic the behavior of built-in slice operations, allowing you to control how slices are accessed, modified, and combined. This will involve working with slice indexing, slicing syntax, and potentially capacity and underlying array behavior.
Specifically, you need to implement the following functions:
GetElement(slice []int, index int) (int, error): Returns the element at a given index. Returns an error if the index is out of bounds.SubSlice(slice []int, start, end int) ([]int, error): Returns a new slice containing elements fromstart(inclusive) toend(exclusive). Returns an error for invalidstartorendindices.AppendElement(slice []int, element int) []int: Appends a single element to the end of a slice.AppendSlice(slice1, slice2 []int) []int: Appends all elements ofslice2to the end ofslice1.CopySlice(source []int, destination []int) (int, error): Copies elements fromsourcetodestination. Returns the number of elements copied and an error if the destination is too small.
Examples
Example 1:
Input:
slice = []int{1, 2, 3, 4, 5}
index = 2
Output:
2, nil
Explanation: The element at index 2 (0-based) is 3.
Example 2:
Input:
slice = []int{1, 2, 3, 4, 5}
start = 1
end = 4
Output:
[]int{2, 3, 4}, nil
Explanation: Elements from index 1 up to (but not including) index 4 are {2, 3, 4}.
Example 3:
Input:
slice = []int{1, 2, 3}
element = 4
Output:
[]int{1, 2, 3, 4}
Explanation: The element 4 is appended to the original slice.
Example 4:
Input:
slice1 = []int{1, 2}
slice2 = []int{3, 4, 5}
Output:
[]int{1, 2, 3, 4, 5}
Explanation: All elements of slice2 are appended to slice1.
Example 5:
Input:
source = []int{1, 2, 3}
destination = []int{0, 0, 0, 0, 0}
Output:
3, nil
destination becomes []int{1, 2, 3, 0, 0}
Explanation: The first 3 elements of source are copied into destination.
Example 6 (Edge Case):
Input:
slice = []int{1, 2, 3}
index = 5
Output:
0, errors.New("index out of bounds")
Explanation: The index 5 is greater than the length of the slice (3), so an out-of-bounds error is returned.
Example 7 (Edge Case):
Input:
source = []int{1, 2, 3}
destination = []int{0, 0}
Output:
0, errors.New("destination slice is too small")
Explanation: The destination slice can only hold 2 elements, but source has 3 elements to copy.
Constraints
- Slice elements will be integers (
int). - Indices for
GetElementandSubSlicewill be non-negative. - For
SubSlice,startwill be less than or equal toend. - Performance is not a primary concern for this challenge; focus on correctness and understanding slice mechanics.
Notes
- Consider how Go handles slice indexing and slicing syntax.
- Pay attention to the lengths and capacities of slices when performing append operations.
- For error handling, use the
errorspackage. - You are implementing these functions as if the built-in equivalents did not exist. Do not use
appenddirectly within yourAppendElementorAppendSliceimplementations, and do not usecopydirectly within yourCopySliceimplementation. Instead, simulate their behavior using loops and slice indexing.