SoFunction
Updated on 2025-03-03

Golang copying Array or Slice

In Golang, Array is the value type and slice is the reference type. Therefore, there are some differences in assignment or copy between the two. This article will take you to understand the differences between them.

1. Copy array

The array mentioned earlier is a value type, so the array variable name is not a pointer to the first element. In fact, it represents the entire array, and the following two cases will automatically create the array:

Assign an array variable to another array variable

Array variables passed as function parameters

Please see the example:

package main
import "fmt"
func main() {
    sample1 := [2]string{"a", "b"}
    ("Sample1 Before: %v\n", sample1)
    sample2 := sample1
    sample2[0] = "c"
    ("Sample1 After assignment: %v\n", sample1)
    ("Sample2: %v\n", sample2)
    test(sample1)
    ("Sample1 After Test Function Call: %v\n", sample1)
}
func test(sample [2]string) {
    sample[0] = "d"
    ("Sample in Test function: %v\n", sample)
}

Output result:

Sample1 Before: [a b]

Sample1 After assignment: [a b]

Sample2:

Sample in Test function: [d b]

Sample1 After Test Function Call: [a b]

Let's explain a little:

sample1 is assigned to sample2 and then modify the first element in sample2. Print sample1 to verify whether it has any impact, of course no changes. This is because sample1 is assigned to sample2, and a copy of sample1 will be created to sample2, so modifying sample2 will not affect sample1.

Pass sample1 to the test function, and then modify its first element within the function body. After printing sample1, verify whether it has any impact, of course, it does not. The reason is the same. When sample1 is passed to test as a parameter, the copy of sample1 is created and passed in, so the modification will not affect the original sample1.

2. Copy slice

The Golang built-in package provides copy function that can copy slices. The function is as follows, which returns the number of copied elements:

func copy(dst, src []Type) int

Two situations need to be considered when using copy functions:

If the src length is greater than dst, then only the elements of the dst length are copied

If the dst length is greater than src, then only the src length elements are copied

Summary to copy the minimum length element of both: min(src,dst)

It should be noted that once the copy is completed, the modification to the target will not affect the source and vice versa.

We also illustrate with examples:

package main
import "fmt"
func main() {
    src := []int{1, 2, 3, 4, 5}
    dst := make([]int, 5)
    numberOfElementsCopied := copy(dst, src)
    ("Number Of Elements Copied: %d\n", numberOfElementsCopied)
    ("dst: %v\n", dst)
    ("src: %v\n", src)
    //After changing numbers2
    dst[0] = 10
    ("\nAfter changing dst")
    ("dst: %v\n", dst)
    ("src: %v\n", src)
}

The output is as follows:

Number Of Elements Copied: 5

dst: [1 2 3 4 5]

src: [1 2 3 4 5]

After changing dst

dst: [10 2 3 4 5]

src: [1 2 3 4 5]

3. Summary

This article introduces direct copying of Go Array and Slice. Array is a value type that is a copy, and Slice is a reference type. Direct assignment is a pointer that affects the source Slice, but the assignment function can be implemented through the built-in copy function.

Supplement: Golang byte array copy BlockCopy function implementation

In C#,(Array, Int32, Array, Int32, Int32)Functions are widely used and their meanings are:

Copy the specified number of bytes from the source array starting at a specific offset to the target array starting at a specific offset.

Parameters src Array Source buffer. srcOffset The byte offset in Int32 src, starting from zero. dst Array destination buffer. dstOffset The byte offset in Int32 dst, starting from zero. count Int32 Number of bytes to be copied.

The implementation in the go language is as follows:

func blockCopy(src []byte, srcOffset int, dst []byte, dstOffset, count int) (bool, error) {
    srcLen := len(src)
    if srcOffset > srcLen || count > srcLen || srcOffset+count > srcLen {
        return false, ("Source buffer index out of range")
    }
    dstLen := len(dst)
    if dstOffset > dstLen || count > dstLen || dstOffset+count > dstLen {
        return false, ("Target buffer index out of range")
    }
    index := 0
    for i := srcOffset; i < srcOffset+count; i++ {
        dst[dstOffset+index] = src[srcOffset+index]
        index++
    }
    return true, nil
}

The above is personal experience. I hope you can give you a reference and I hope you can support me more. If there are any mistakes or no complete considerations, I would like to give you advice.