Original link: The difference between Go language array and slice
In the Go language, arrays and slices look similar, but in fact they have many differences. This article will talk about the differences between them.
In addition, this question is often asked in interviews. It is an entry-level question. After reading the article, I believe you will have a good answer.
array
An array is a collection of elements of the same data type. When defining an array, the length and element type need to be specified.
For example: [4]int represents an array containing four integers, and the size of the array is fixed. And the length is part of its type ([4]int and [5]int are different, incompatible types).
Array elements can be accessed by index, for example, the expression s[n] means to access the nth element, and the index starts from zero.
declaration and initialization
func main() { var nums [3]int // declared and initialized to a default zero value var nums1 = [4]int{1, 2, 3, 4} // Declare simultaneous initialization var nums2 = [...]int{1, 2, 3, 4, 5} // ...can represent the length of the subsequent initialization value fmt.Println(nums) // [0 0 0] fmt.Println(nums1) // [1 2 3 4] fmt.Println(nums2) // [1 2 3 4 5] }
function parameters
If an array is used as a parameter of a function, what is actually passed is a copy of the array, not a pointer to the array. This also means that modifying the elements of the array in the function will not affect the original array.
package main import ( "fmt" ) func Add(numbers [5]int) { for i := 0; i < len(numbers); i++ { numbers[i] = numbers[i] + 1 } fmt.Println("numbers in Add:", numbers) // [2 3 4 5 6] } func main() { // declare and initialize the array var numbers [5]int for i := 0; i < len(numbers); i++ { numbers[i] = i + 1 } Add(numbers) fmt.Println("numbers in main:", numbers) // [1 2 3 4 5] }
slice
The usage scenarios of arrays are relatively limited, and slices are more commonly used.
A Slice is a variable-length sequence of elements of the same type. It is a layer of encapsulation based on the array type. It is very flexible and supports automatic expansion.
A slice is a reference type that has three properties: pointer, length and capacity.
- Pointer: Points to the first element accessible by the slice.
- Length: the number of elements in the slice.
- Capacity: the number of elements between the start element of the slice and the last element of the underlying array.
The underlying source code is defined as follows:
type slice struct { array unsafe.Pointer len int cap int }
declaration and initialization
func main() { var nums []int // declare slice fmt.Println(len(nums), cap(nums)) // 0 0 nums = append(nums, 1) // initialization fmt.Println(len(nums), cap(nums)) // 1 1 nums1 := []int{1,2,3,4} // declare and initialize fmt.Println(len(nums1), cap(nums1)) // 4 4 nums2 := make([]int,3,5) // Use the make() function to construct slices fmt.Println(len(nums2), cap(nums2)) // 3 5 }
function parameters
When a slice is used as a function parameter, unlike an array, if a function accepts a slice parameter, the changes it makes to the slice elements will be visible to the caller, similar to passing a pointer to the underlying array.
package main import ( "fmt" ) func Add(numbers []int) { for i := 0; i < len(numbers); i++ { numbers[i] = numbers[i] + 1 } fmt.Println("numbers in Add:", numbers) // [2 3 4 5 6] } func main() { var numbers []int for i := 0; i < 5; i++ { numbers = append(numbers, i+1) } Add(numbers) fmt.Println("numbers in main:", numbers) // [2 3 4 5 6] }
Look at the above example again, change the parameter from an array to a slice, and the modification in the Add function will affect the main function.
Summarize
Finally, to sum up, you can also answer this way during the interview:
- An array is a fixed-length data type whose length is determined at the time of definition and cannot be changed dynamically; a slice is a variable-length data type whose length can be empty when defined or an initial length can be specified.
- The memory space of the array is allocated at the time of definition, and its size is fixed; the memory space of the slice is dynamically allocated at runtime, and its size is variable.
- When an array is used as a function parameter, the function operates on a copy of the array and does not affect the original array; when a slice is used as a function parameter, the function operates on a reference to the slice, which affects the original slice.
- Slices also have the concept of capacity, which refers to the allocated memory space.
The above is the whole content of this article. If you think it is not bad, please like, repost and follow. Thank you for your support.
Reference article:
- https://go.dev/doc/effective_go#arrays
- https://go.dev/blog/slices-intro
- https://levelup.gitconnected.com/go-programming-array-vs-slic...
Recommended reading:
- The difference between new and make keywords in Go language
- [Why Go doesn't support conversion of []T to []interface]( https://mp.weixin.qq.com/s/cwDEgnicK4jkuNpzulU2bw)
- Why Go language struct uses tags