How to Remove an Element from a Slice in Golang: Detailed Guide with Examples
\n\nWorking with slices in Go is a daily routine for every developer. But one operation raises questions even among experienced "gophers": removing an element from a slice. It seems simple, right? However, Go does not have a built-in delete() method for slices, unlike maps. You have to reinvent the wheel.
In this article, we will cover all ways to remove an element from a slice in Golang: from simple removal by index to advanced tricks with order preservation and memory optimization. You will learn how the internal mechanics of slices work, why simple assignment doesn't always work, and how to avoid common mistakes.
\n\nWhy is there no built-in function to delete from a slice in Go?
\n\nBefore diving into the code, let's understand the language's philosophy. A slice in Go is simply a "window" into an underlying array. It does not own the data, it only references it. Therefore, deleting an element is not about physically erasing data from memory (as in C++), but about restructuring the "window" using clever append and slicing operations.
Go lets you decide how to organize the deletion: with or without order preservation, with or without capacity reduction. This provides flexibility but requires understanding.
\n\nMethod 1: Removal by Index (with Order Preservation)
\n\nThis is the most common case. You have a slice and want to remove the element at position i while preserving the relative order of the remaining elements.
package main\n\nimport "fmt"\n\nfunc removeIndex(s []int, index int) []int {\n // Combine the part before the index and the part after the index\n return append(s[:index], s[index+1:]...)\n}\n\nfunc main() {\n slice := []int{1, 2, 3, 4, 5}\n slice = removeIndex(slice, 2) // remove element at index 2 (value 3)\n fmt.Println(slice) // [1 2 4 5]\n}\n\n\nHow it works:
\n- \n
s[:index]— takes all elements before the one to be removed (excluding it). \n s[index+1:]— takes all elements after the one to be removed. \n appendcombines these two "pieces" into one slice. \n
Important: This method modifies the underlying array. After the operation, element 3 physically remains in memory (it will only be overwritten if you add new elements). But for you, it has "disappeared" from the slice.
Method 2: Removal by Index (without Order Preservation) — Fast Method
\n\nIf the order of elements does not matter (e.g., you are working with an unordered set of data), you can use the "swap with last" trick:
\n\nfunc removeFast(s []int, index int) []int {\n // Replace the element to be removed with the last element\n s[index] = s[len(s)-1]\n // Trim the slice, discarding the last element\n return s[:len(s)-1]\n}\n\nfunc main() {\n slice := []int{1, 2, 3, 4, 5}\n slice = removeFast(slice, 1) // remove element at index 1 (value 2)\n fmt.Println(slice) // [1 5 3 4] — order is broken!\n}\n\n\nWhy is this faster? Because we do not copy half of the slice. We simply move one element (the last one) to the position of the removed element and truncate the slice. This is an O(1) operation versus O(n) for the first method.
\n\nWhen to use: In hot loops where performance is critical and order does not matter (e.g., when removing from an object pool).
\n\nMethod 3: Removal by Value (First Occurrence)
\n\nOften you need to find and remove an element by its value, not by its index. To do this, first find the index, then apply one of the methods above.
\n\nfunc removeByValue(s []string, value string) []string {\n for i, v := range s {\n if v == value {\n return append(s[:i], s[i+1:]...)\n }\n }\n return s // if not found, return the original slice\n}\n