← Back to Go Course | Chapter 5: Arrays Slices Maps | Lesson 4 of 7

Copying Slices

copy() makes a real, separate duplicate of a slice's contents, so changing the copy never touches the original.
Syntax
go
n := copy(dst, src)

Using copy()

The built-in copy function copies elements from a source slice into a destination slice, and unlike plain assignment, the two slices end up backed by completely separate memory afterward.

Example: Using copy()

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the fmt package
import "fmt"

// main is where the program starts running
func main() {
	// Short declaration: create src and infer the type
	src := []int{1, 2, 3}
	// Short declaration: create dst and infer the type
	dst := make([]int, 3)
	n := copy(dst, src)
	// Print the values followed by a newline
	fmt.Println("copied:", n, "dst:", dst)
}

copy() Is Limited by the Shorter Slice

copy only transfers as many elements as fit in the smaller of the two slices -- if the destination is shorter than the source, the extra source elements are simply left out, with no error raised.

Note: Make sure the destination slice is at least as long as the source before copying, using make(len(src)) if needed.

Example: copy() Is Limited by the Shorter Slice

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the fmt package
import "fmt"

// main is where the program starts running
func main() {
	// Short declaration: create src and infer the type
	src := []int{1, 2, 3, 4, 5}
	// Short declaration: create dst and infer the type
	dst := make([]int, 2)
	n := copy(dst, src)
	// Print the values followed by a newline
	fmt.Println("copied:", n, "dst:", dst)
}

Independence After Copying

Once copy() has run, modifying the destination slice never affects the source, and vice versa -- they are backed by entirely separate underlying arrays, which is the whole point of using copy instead of assignment.

Example: Independence After Copying

markup
// Every Go file belongs to a package; main builds an executable
package main

// Import the fmt package
import "fmt"

// main is where the program starts running
func main() {
	// Short declaration: create original and infer the type
	original := []int{1, 2, 3}
	// Short declaration: create duplicate and infer the type
	duplicate := make([]int, len(original))
	copy(duplicate, original)
	duplicate[0] = 999
	// Print the values followed by a newline
	fmt.Println("original:", original)
	// Print the values followed by a newline
	fmt.Println("duplicate:", duplicate)
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Assigning one slice variable to another ('b := a') expecting an independent copy, when it actually just shares the same underlying array.
  2. Calling copy(dst, src) with dst having fewer elements than src, and not realizing copy silently only copies up to len(dst).
  3. Forgetting copy() returns the number of elements actually copied, which is useful for verifying a full copy happened.
Chapter Summary
  • copy(dst, src) copies elements from src into dst, up to the length of the shorter one.
  • copy() is the way to create a truly independent slice, unlike plain assignment.
  • The number of elements copied is limited by whichever slice (dst or src) is shorter.
  • copy() returns an int: how many elements were actually copied.
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.