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.