Meng小羽

Debug客栈

永远相信美好的事情即将发生! 非标准程序猿 / 🧑‍💻爱编码 / 📹爱摄影 / ⛰️爱徒步 / ❤️更爱女朋友 / 米家好物推荐官 关注我哦,让我们一起变得更强~
github
x
bilibili
zhihu
youtube
follow
email

Go Language Basics: Arrays, Slices, Maps

In the Go language, the data structure design for storing and managing user data is divided into three types: Array, Slice, and Map.

Recently, I have also looked at the basics of Go language and the implementation principles of these three structures:

Array#

  • Arrays are the basic data structures for slices and maps;
  • Arrays are fixed-length data types and are also continuously allocated in memory, so accessing indexed array data is very fast;
  • When declaring an array, you need to specify the type and quantity of the array (the length of the array);
  • The type of an array variable includes the length of the array and the type of its elements. Only arrays with both parts the same can be assigned to each other.

Creation and Initialization#

Once an array is declared, its data type and length cannot be changed.

// Declare an array using array literals
array := [5]int{1, 2, 3, 4, 5}

// Automatically infer the length to declare an array
array := [...]int{1, 2, 3, 4, 5, 6}
// Use ... instead of the length, and infer based on the number of initialized elements

// Declare an array and specify specific element values
array := [5]int{1:10, 2:20}

Pointer Type#

The type of array elements can be any built-in type, a certain structure type, or a pointer type.

// Declare a pointer array with an element length of 3 pointing to a string
var array1 [3]*string

// Specify elements for the pointer array
*array1[0] = "demo0"
*array1[1] = "demo1"
*array1[2] = "demo2"

Multidimensional Array#

An array itself is one-dimensional data, and a multidimensional array is composed of multiple arrays.

// Declare a two-dimensional array
var array = [3][2]int
// Declare an element with two dimensions of 3 and 2

// Initialize a two-dimensional array
var array = [3][2]int{ {1, 2}, {3, 4}, {5, 6}}

Passing Arrays Between Functions: Since only the value of the variable is passed when passing variables between functions, the entire array will be copied when passing an array variable! When defining a function, for larger data types, the parameter should be designed as a pointer type. In this way, when calling the function, only 8 bytes of memory need to be allocated for each pointer on the stack. However, this means that the value pointed to by the pointer (shared memory) will be changed. In fact, in most cases, the slice type should be used instead of an array.

Slice#

  • Slice is a reference type that refers to a part or all of the underlying array pointed to by its pointer field;
  • Slice is built around the concept of dynamic arrays;
  • The dynamic growth of a slice is achieved through append;
  • Shrinking is achieved by slicing it again. The new slice obtained by slicing again will share the underlying array with the original slice, and their pointers point to the same underlying array.

Creation and Initialization#

A slice type has three fields:

  • Pointer: points to the address of the first element included in the slice in the underlying array;
  • Length: the number of elements in the underlying array included in the slice (the number of elements accessible by the slice);
  • Capacity: the maximum number of elements that the slice can grow to, which is the length of the underlying array.

make and slice literals

// Create a slice using make
slice := make([]int, 3)

// Create a slice with a length and capacity
slice := make([]int, 1, 6)
// Length is 1, capacity is 6 elements

nil and empty slices

// Nil string slice
var slice []string

// Empty slice
slice := []int{}
// Empty integer slice

Since a slice only refers to the underlying array, the data of the underlying array does not belong to the slice itself. Therefore, a slice only needs 24 bytes of memory (on a 64-bit machine): 8 bytes for the pointer field, 8 bytes for the length field, and 8 bytes for the capacity field. Therefore, passing a slice directly between functions is efficient, only requiring 24 bytes of stack memory to be allocated.

The len function returns the length of the slice, and the cap function returns the capacity of the slice.

Map#

  • A map is used to store a series of unordered key-value pairs;
  • Maps are unordered collections, and their implementation uses hash tables;
  • The hash table of a map contains a set of buckets, each of which stores a part of the key-value pairs;
  • The map internally uses two arrays:
    • The first array: stores the high eight-bit values of the hash keys used to select buckets, which is used to determine which bucket each key-value pair should be stored in;
    • The second array: each bucket has a byte array, which first stores all the keys in the bucket in order, and then stores all the values in the bucket.

Creation and Initialization#

// Create a map to store student information
students := map[string]string{
    "name" : "mengxiaoyu",
    "age"  : "22",
    "sex"  : "boy",
    "hobby": "pingpang",
}

// Display all information in the map
for key, value := range students{
    fmt.printf("key:%s, \t value:%s\n", key, value);
}

The order of traversing the key-value pairs of a map is random. If you want to obtain the key-value pairs of a map in order, you need to first traverse the keys of the map and store them in a slice, then sort the slice, and finally traverse the slice to retrieve the corresponding values from the map according to the order of the elements in the slice.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.