Write before
- Well, learn GO, so I have this article
- Bowen is one of the reading notes of GO Language Actual War
- Mainly related to array knowledge
No one in the world is supposed to be nice to you except your parents. Jianlai, Prince of Fire Play
Internal implementation and basic functions of arrays
Arrays are the basic data structures for slicing and mapping in GO, and little partners who have learned other languages should be familiar with arrays. Basically all languages have the concept of arrays.
Array is a linear data structure. It uses a continuous set of memory space to store a set of data of the same type.
Internal implementation
In the Go language, an array is a fixed-length data type used to store a continuous block of elements of the same type. The type of array storage can be a built-in type, such as an integer or string, or a structure type.
Arrays are allocated continuously because of their memory footprint. The CPU can cache data in use for longer. It's also easy to compute an index with continuous memory, which allows you to quickly iterate over all elements in an array. The type information of the array provides the distance that needs to be moved in memory each time an element is accessed.
I personally understand the above statement:
- Memory is allocated continuously on the array structure, so it is easy to compute the index (relative address of the elements), the column of equal difference, and the memory is continuous, which makes it very good to use the CUP cache. When the CPU accesses the first address, it automatically loads the other elements of the current array into the CUP Cache from memory, and how much to load is determined by the CPU Cache Line. So the CPU can cache the data it is using for longer. When memory is not continuous, CPU Cache cannot be read, data elements can only be read from memory repeatedly, and CPU Cache features cannot be fully utilized.
- Indexing allows you to iterate over array elements quickly. If A is used to represent the first address of the array, a[0] is the position with an offset of 0, that is, the first address, and a[k] is the offset of K type_size's location, so calculating the memory address of a[k] only requires this formula a[k]_address = base_address + k * type_size, so you can quickly iterate through the index to confirm the memory address, and in theory time replication is constant.
Declarations and Initializations
Declaring an array requires specifying the type of data stored internally and the number of elements to store
- Declare an array and set it to zero
var arrays [5]int
- Declare arrays using array literals
arrays := [5]int{10,12,13}
- Let Go automatically calculate the length of the declaration array
array := [...]int{10, 20,30, 40, 50}
- Declare arrays and specify values for specific elements, initializing elements indexed 1 and 2 with specific values
array := [5]int{1: 10, 2: 20}
Using arrays
Memory layouts are continuous, so arrays are efficient data structures that use the [] operator when accessing any element in an array
- Accessing array elements
//Declare an integer array containing five elements array := [5]int{10, 20, 30, 40, 50} // Modify the value of the element with index 2 array[2] = 35
Declares an array in which all elements are pointers. Use the * operator to access the value pointed to by the element pointer
- Access elements of pointer array
// Declare an array of integers containing five elements // Initialize array elements indexed 0 and 1 with integer pointers array := [5]*int{0: new(int), 1: new(int)} // Assign values to elements with index 0 and 1 *array[0] = 10 *array[1] = 20
In the Go language, an array is a value. This means that arrays can be used in assignment operations. Variable names represent the entire array, and arrays of the same type can be assigned to another array
// Declare the first string array containing five elements var array1 [5]string // Declare the second string array containing five elements // Initialize Array with Color array2 := [5]string{"Red", "Blue", "Green", "Yellow", "Pink"} // Copy the value of array2 to array1 array1 = array2
- Compilers prevent arrays of different types from assigning values to each other
package main import "fmt" func main() { fmt.Println("Hello World") // Declare the first string array containing four elements var array1 [4]string // Declare the second string array containing five elements // Initialize Array with Color array2 := [5]string{"Red", "Blue", "Green", "Yellow", "Pink"} // Copy array2 to array1 array1 = array2 }
go vet check
┌──[root@liruilongs.github.io]-[/usr/local/go/src/demo] └─$go fmt array.go array.go ┌──[root@liruilongs.github.io]-[/usr/local/go/src/demo] └─$vim array.go ┌──[root@liruilongs.github.io]-[/usr/local/go/src/demo] └─$go vet array.go # command-line-arguments vet: ./array.go:15:11: cannot use array2 (variable of type [5]string) as [4]string value in assignment ┌──[root@liruilongs.github.io]-[/usr/local/go/src/demo] └─$
Multidimensional Array
The array itself has only one dimension, but you can combine multiple arrays to create a multidimensional array. Multidimensional arrays make it easy to manage data with parent-child relationships or data associated with coordinate systems
- Declare a two-dimensional array
// Declare a two-dimensional array of integers that store four and two elements, respectively, in two dimensions var array [4][2]int // Declare and initialize a two-dimensional integer array using an array literal array := [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}} // Declare and initialize elements indexed to 1 and 3 in the outer array array := [4][2]int{1: {20, 21}, 3: {40, 41}} // Declare and initialize individual elements of outer and inner arrays array := [4][2]int{1: {0: 20}, 3: {1: 41}}
- Accessing the elements of a two-dimensional array
// Declare a 2 × 2-D integer array var array [2][2]int // Set the integer value of each element array[0][0] = 10
Multidimensional arrays can be assigned to each other as long as the types are identical
// Declare two different arrays of two-dimensional integers var array1 [2][2]int var array2 [2][2]int // Assigning values to each element array2[0][0] = 10 array2[0][1] = 20 array2[1][0] = 30 array2[1][1] = 40
- Multidimensional array assignment of the same type
// Copy the value of array2 to array1 array1 = array2
- Assigning values to multidimensional arrays using indexes
// Copy the dimension with index 1 of array1 into a new array of the same type var array3 [2]int = array1[1] // Copy the integer value with index 1 of outer array and index 0 of inner array into the new integer variable var value int = array1[1][0]
Passing Arrays Between Functions
Passing an array between functions is an expensive operation in terms of memory and performance. When variables are passed between functions, they are always passed by value. If the variable is an array, it means that the entire array, no matter how long, is copied completely and passed to the function.
- Pass large arrays between functions using value passing
// Declare an array that requires 8 MB and create an array containing 1 million int-type elements var array [1e6]int // Pass Array to Function foo foo(array) // Function foo accepts an array of 1 million integer values func foo(array [1e6]int) { ... }
Each time a function foo is called, 8 MB of memory must be allocated on the stack
There is also a better and more efficient way to handle this operation. You can just pass in a pointer to the array, so you only need to copy 8 bytes of data instead of 8 MB of memory data onto the stack
- Passing large arrays between functions using pointers
// Assign an array that requires 8 MB var array [1e6]int // Pass the address of the array to the function foo foo(&array) // The function foo accepts a pointer to an array of 1 million integer values func foo(array *[1e6]int) { ... }
To pass the address of an array into a function, you only need to allocate 8 bytes of memory on the stack to the pointer.