This is a creation in Article, where the information may have evolved or changed.
arrays, slices, and mappings are the most important data structures for Golang, and here is a personal summary of these 3 data structures:
One, array
- Arrays are the underlying data structures for slices and mappings.
- An array is a fixed-length data type that stores a contiguous block of memory with elements of the same data type.
- Since the memory occupied by the array is continuously allocated, the operation of the arrays is fast.
- How to declare an array: 4 types
- var array1 [5]int
- Array1: = [5]int{3,5,6,3,2}
- Array1: = [...] int{3,4,7,8,1}//determines the length of an array based on the number of elements in the array literal
- Array1: = [5]int{0:3,3:5,4:8}//Initialize only the elements of the specified index, remaining elements remain 0 values
- The type of an array element can be any built-in type, or it can be a struct type, or a pointer type.
- The type of the array variable includes the array length and the element type, and only two parts of the same array can be assigned to each other.
- Multidimensional arrays: The array itself has only one dimension, and can only be created by combining multiple arrays to create a multidimensional array
- var array [4][2]int
- Array: = [4][2]int{2:{20,21},3:{41,25}}
- Array: = [4][2]int{2:{1:21},3:{0:41}}
- ARRAY[2][1] = 10
- Passing an array between functions: Because the passing of a variable between functions is always a copy of the value of the variable, the entire array is copied when the array variable is passed! When defining a function, the parameter should be designed as a pointer type for a large data type, so that when the function is called, only 8 bytes of memory is allocated to each pointer on the stack, but this means that the value that the pointer points to (shared memory) is changed, but in most cases the slice type should be used instead of the array.
second, sliced slice
- A slice slice is a reference type that references part or all of the underlying array to which its pointer fields point.
- Create and initialize:
- Slice1: = Make ([]string, 5)//Create a one-length, 5-size slice of type string
- Slice1: = Make ([]string, 3, 5)//Create a string-type slice with a length of 3 and a capacity of 5
- Slice2: = []string{"Red", "Blue", "green"}//length and size 3 slices
- Slice2: = []int{99:1}//length and capacity are 100, and initialization 100th element is 1
- The length of the slice can automatically grow or shrink as needed:
- Dynamic growth is achieved through the append () function, and the maximum length must not exceed the capacity value
- Shrinking is done by slicing it again, and new slices obtained from the slice will share the underlying array with the original slice, and their pointers point to the same underlying array.
- Slice again: Assuming that the original slice slice capacity is k, the new slice newslice visible Bottom array portion is the original slice of the 0 indexed element position starting to the end of the underlying array
- Newslice: = slice[i:j]//New slice contains the original slice slice of the visible underlying array portion of the element starting to the first J element, i.e. the element indexed as j-1, the length of the new slice is j-i, the capacity is K-i
- Newslice: = slice[i:j: n]//New slice contains the original slice slice of the visible underlying array portion of the element starting to the first J element, that is, the element indexed as j-1, the length of the new slice is j-i, and the capacity is N-i (the third parameter n-1 indicates that the new slice can be extended to The last visible element index of the underlying array section, thus achieving the purpose of limiting capacity, note: n must be >=j)
- The new slice cannot access the part before the first element of the underlying array to which it points (the part before the first index)
- Example: ss:=[]int{10,20,30,40,50} Newss:=ss[2:4:5]//newss for [30,40] with a capacity of 3
- There are 3 fields for a slice type:
- Pointer: The address in the underlying array that points to the first element that the slice contains
- Length: The number of elements of the underlying array that the slice contains (the number of elements that can be accessed by the slice)
- Capacity: The maximum number of elements that a slice allows to grow, that is, the length of the underlying array
- Since the slice simply refers to the underlying array, the data for the underlying array is not part of the slice itself, so a slice requires only 24 bytes of memory (on a 64-bit machine): Pointer field 8 bytes, Length field 8 bytes, capacity field 8 bytes. So it is efficient to pass slices directly between functions, allocating only 24 bytes of stack memory.
- Nil slices and empty slices:
- Nil Slice: A slice that is only declared but not initialized, such as Var Slice1 []int,nil Slice can be used to describe a nonexistent slice
- Empty slices: slices with a length and capacity of 0, no memory is allocated to the element when an empty slice is created, and can be used to represent an empty collection, such as Slice1: = Make ([]int, 0), Slice2: = []int{}
- Call built-in functions like Append, Len, and cap for nil slices and empty slices
- Append () function:
Slice = append (slice, elem1, elem2)//can append multiple values at one time
Slice = append (slice, anotherslice ...) Use "..." to append all elements of anotherslice to slice
- When slice has available capacity, the append () operation merges the available elements into the length of the slice, assigns it a value, and finally returns a completely new slice (sharing the same underlying array with the old slice);
- If the capacity of the slice is insufficient, the append () operation creates a new underlying array, copies the referenced old values into the new array, and appends the new values;
- When the original slice capacity is insufficient, and less than 1000, then the capacity of the new slice is twice times the original capacity, if greater than 1000, the growth factor of capacity becomes 1.25;
- Due to insufficient capacity, the append operation returns a new slice with its own independent underlying array, which does not share the same underlying array as the original slice, and the modification of the new slice element will not affect the underlying array of the original slice, tip: Set the length equal to the capacity when creating the slice. This forces the creation of a new underlying array to be separated from the original array at the first append operation, such as newslice: = Oldslice[2:3:3]
- The iterations of the slice are as follows: For index, value range slice{....},index is the current iteration to the index position, value is the temporary copy of the current index position element, the memory address of index and value variable is constant, but the value pointed to is constantly updated.
- The Len function returns the length of the slice, and the CAP function returns the slice's capacity
- Multidimensional slices: slices and arrays, which are themselves one-dimensional, can combine multiple slices to form a multidimensional slice, such as: slice: = [][]int{{12},{34,23}},slice[0] {12},slice[1] = {34,23}
third, mapping map
- Mapping map: Is an unordered collection of key-value pairs that can quickly retrieve data based on a key, which, like an index, points to the value associated with the key;
- The mapping is unordered, and the order may be different each time it iterates, because the map uses a hash table internally;
- The mapped hash table contains a set of buckets, each of which stores a subset of key-value pairs;
- The mapping internally uses two arrays:
- First array: A high eight-bit value that stores the hash key for the selection bucket, which is used to distinguish which bucket each key-value pair is to exist in;
- Second array: Each bucket has a byte array, which stores all the keys in the bucket, and then stores all the values of the bucket;
- When storing, deleting, and locating a mapped key-value pair, the specified key is passed to the mapped hash function, which converts the key to a hash value, and then chooses which bucket to match the hash value to the first array, and then finds the corresponding key and value in the byte array in the bucket;
- To create and initialize a map:
- Dict1: = Make (map[string]int)//null mapping, equivalent to Dict1: = map[string]int{}
Dict2: = map[string]int{"SRF": 143, "ROBT": 342}
- Mapped keys: Can be any type that can be compared with "= =", but not slices, functions, and types that contain slices because they have referential semantics. The value of the map can be any type;
- The nil mapping is a declaration-only, uninitialized mapping that cannot be used directly, such as Var dict map[string]int. The empty mapping can be used directly;
- To take a value from the map:
- Value: = dict2["SRF"]//key is present when the corresponding value is returned, no 0 value of the return type exists
- Value, OK: = dict2["SRF"]//ok the Boolean flag for whether the key exists
If OK {...}
- Traversal mappings:
- For key: = Range Dict2 {...}//Receive key only
- For key, Value: = Range dict2 {...}//Receive both the key and the value
- The order of the key-value pairs that traverse the mappings is random, to get the mapped key-value pairs in order, you need to walk out the mapped key to a slice, then sort the slice, and finally traverse the slice to map the corresponding values in the order of the elements in the slice
- Delete (Dict2, "SRF") removes the specified key-value pair from the map;
- Passing a map between functions is like passing a slice, just passing a copy of the map itself without duplicating all the underlying data structures referenced by the map, and modifications to that mapped copy will be reflected in all references to that mapping.
- Multidimensional mapping: A mapping with a value of a mapping type. It should be noted that mapping as a value also needs to be initialized before it can be used, such as:
var m1 = make (map[int]map[string]string)
m1[13]= map[string]string{"SRF": "Yes"}