Golang slices.Clone
last modified April 20, 2025
This tutorial explains how to use the slices.Clone function in Go.
We'll cover slice cloning operations with practical examples.
The slices.Clone function creates a new slice that is a shallow copy of the original slice. It's part of Go's experimental slices package.
This function is useful when you need an independent copy of a slice to prevent unintended modifications to the original data. It returns a new slice with the same elements.
Basic slices.Clone Example
The simplest use of slices.Clone creates a copy of a string slice.
We can then modify the copy without affecting the original.
package main
import (
"fmt"
"slices"
)
func main() {
original := []string{"apple", "banana", "cherry"}
clone := slices.Clone(original)
clone[0] = "orange"
fmt.Println("Original:", original)
fmt.Println("Clone:", clone)
}
We create a clone of the original slice and change its first element. The original slice remains unchanged, demonstrating independent copies.
Cloning Integer Slices
slices.Clone works with any slice type. This example clones a slice
of integers and modifies the copy.
package main
import (
"fmt"
"slices"
)
func main() {
nums := []int{1, 2, 3, 4, 5}
numsCopy := slices.Clone(nums)
numsCopy[0] = 100
numsCopy = append(numsCopy, 6)
fmt.Println("Original:", nums)
fmt.Println("Clone:", numsCopy)
}
The clone starts with the same elements but can be modified independently. We change an element and append a new value without affecting the original.
Cloning Struct Slices
When cloning slices of structs, remember it's a shallow copy. This example shows how struct fields remain shared between original and clone.
package main
import (
"fmt"
"slices"
)
type Point struct {
X, Y int
}
func main() {
original := []Point{{1, 2}, {3, 4}}
clone := slices.Clone(original)
clone[0].X = 100
fmt.Println("Original:", original)
fmt.Println("Clone:", clone)
}
Modifying a struct field in the clone affects the original because the structs are shared. The slice headers are different but point to the same struct values.
Empty Slice Behavior
slices.Clone handles empty slices gracefully. This example
demonstrates cloning an empty slice and checking its properties.
package main
import (
"fmt"
"slices"
)
func main() {
empty := []int{}
clone := slices.Clone(empty)
fmt.Println("Original len:", len(empty), "cap:", cap(empty))
fmt.Println("Clone len:", len(clone), "cap:", cap(clone))
clone = append(clone, 1)
fmt.Println("Modified clone:", clone)
}
The clone is a new empty slice with the same type. We can append to it without affecting the original empty slice, which remains empty.
Performance Considerations
For large slices, cloning has memory and performance implications. This example benchmarks cloning different sized slices.
package main
import (
"fmt"
"slices"
"time"
)
func main() {
sizes := []int{100, 10_000, 1_000_000}
for _, size := range sizes {
slice := make([]int, size)
start := time.Now()
_ = slices.Clone(slice)
elapsed := time.Since(start)
fmt.Printf("Size: %d, Time: %v\n", size, elapsed)
}
}
The time taken increases with slice size. slices.Clone allocates new
memory and copies all elements, so consider performance for large slices.
Comparing with Manual Copy
This example compares slices.Clone with manual slice copying using
append or make+copy.
package main
import (
"fmt"
"slices"
)
func main() {
original := []int{1, 2, 3, 4, 5}
// Method 1: slices.Clone
clone1 := slices.Clone(original)
// Method 2: append
clone2 := append([]int(nil), original...)
// Method 3: make + copy
clone3 := make([]int, len(original))
copy(clone3, original)
// Modify all clones
clone1[0] = 100
clone2[0] = 200
clone3[0] = 300
fmt.Println("Original:", original)
fmt.Println("Clone1:", clone1)
fmt.Println("Clone2:", clone2)
fmt.Println("Clone3:", clone3)
}
All three methods create independent copies. slices.Clone provides
a cleaner, more readable alternative to manual copying techniques.
Practical Example: Immutable Function Parameters
This practical example shows how to use slices.Clone to protect
function parameters from modification.
package main
import (
"fmt"
"slices"
)
func processData(data []string) []string {
// Create a local copy to prevent modifying input
localCopy := slices.Clone(data)
// Modify the copy
for i := range localCopy {
localCopy[i] = "processed_" + localCopy[i]
}
return localCopy
}
func main() {
original := []string{"a", "b", "c"}
result := processData(original)
fmt.Println("Original:", original)
fmt.Println("Result:", result)
}
By cloning the input slice, we ensure the original data remains unchanged. This is a common pattern when working with slice parameters in functions.
Source
Go experimental slices package documentation
This tutorial covered the slices.Clone function in Go with practical
examples of creating independent slice copies in various scenarios.
Author
List all Go tutorials.