map data type in Golang

Keywords: Go

Today, let's learn about the map data type in golang, simply summarize the basic syntax and usage scenarios, and don't go deep into the bottom. What is the map type? Having done PHP, it is no stranger to the data type of array. Arrays in PHP are divided into index arrays and associative arrays. For example, the following code:

// Index array [the key of the array is a number, increasing from 0, 1 and 2]
$array = [1, 'Zhang San', 12];
// Associative array [the key of the array is a string, and the name of the key can be customized]
$array = ['id' => 1, 'name' => 'Zhang San', 'age' => 12];

In golang, map is a special data structure. It is a structure in which a key corresponds to a value type. This structure can be called associative arrays and dictionaries.

There are also data types such as slices and arrays in golang to store a set of data.

  1. Array is like a one-dimensional array in PHP, and its length is fixed. The value type is determined when defining the array.
  2. Slice is a special array type. The length is fixed// Array, type int, length 4. array := [4]int{1, 2, 3, 4} //Slice, type int, length not fixed. Slice: = [] int {1, 2, 3, 4} has arrays and slices that can store a set of data. Why is there a type structure such as map? What is the map type?

case

Suppose we now have a requirement to use a data type in golang to store the data of multiple users. These data are the user's ID, name, age, sex... And other fields. What data type should we use instead?

  1. In PHP, we can define it directly in the following way, and the operation is very simple.
$userInfo = [
  ['id' => 1, 'name' => 'Zhang San', 'age' => 12, 'sex' => 'male'],  
  ['id' => 2, 'name' => 'Zhao Liu', 'age' => 22, 'sex' => 'male'],
  ['id' => 3, 'name' => 'Li Si', 'age' => 34, 'sex' => 'female'],
  ['id' => 4, 'name' => 'Wang Mazi', 'age' => 56, 'sex' => 'male']
];
  1. How to implement it in golang? Suppose we try to implement it with arrays and slices.
// 1. Implement with array
$user1 := [4]string{"1", "Zhang San", "12", "male"}
$user2 := [4]string{"2", "Zhao Liu", "12", "male"}
$user3 := [4]string{"3", "Li Si", "12", "female"}
$user4 := [4]string{"4", "Wang Mazi", "12", "male"}
// 2. User slicing implementation
$user1 := []string{"1", "Zhang San", "12", "male"}
$user2 := []string{"2", "Zhao Liu", "12", "male"}
$user3 := []string{"3", "Li Si", "12", "female"}
$user4 := []string{"4", "Wang Mazi", "12", "male"}

Through the above example code, can we see that there are several problems.

a. Low readability. We don't know what information such as 1 and 12 is about the user. Male and Zhang San, we can also guess the name and gender.

b. Duplicate code. One user is one variable. If there are tens of millions of users, don't we need to define tens of millions of variables.

c. Cumbersome. Compared with the implementation of PHP, it is not very cumbersome. A variable is directly defined in PHP, and the key and value can be defined through multi-dimensional array. Clear and simple. This is why everyone says that arrays in PHP are very powerful and easy to use.

  1. Through slicing and array implementation, we know the disadvantages. Is there a data type that can be implemented as simple as PHP? In such a scenario, you can use a map to implement a definition structure such as PHP. Next, we will summarize the map related operations.

map

map definition

map is a special data structure: an unordered set of element pairs. One element of pair is key and the corresponding element is value. Therefore, this structure is also called associative array or dictionary. This is an ideal structure for quickly finding values: given a key, the corresponding value can be located quickly.

map is also called Dictionary (Python), hash and HashTable in other programming languages.

map declaration

Map is a reference type. When using it, we need to allocate memory space to make. The map value of unallocated memory space is a nil.

map When declaring, you need to specify key And the type of value, and when copying, it must be copied according to the type at the time of definition.
map The value of can be any type, slice, array, interface, structure, pointer, string, etc.
var map1 map[key type]Value type

// Declaration mode 1, complete mode
var map1 map[int]string
map1 = make(map[int]string[, n])

// Declaration mode 2, paragraph syntax style
map1 := make(map[int]string[, n])

The above n is the capacity of the map, that is, the number of elements that the map can store. It can be omitted, and the map will expand dynamically. In the sample small case, we use a map to store the information of a user. User information includes ID, name and age fields.

userInfo := make(map[string]string)
userInfo["id"] = "1"
userInfo["name"] = "Zhang San"
userInfo["age"] = "12"
fmt.Println(userInfo)

// output
map[id:1 name:Zhang San age:12]

Because the fields and field values of user information have string and number types, after defining the type, only the value of the corresponding type can be passed. Therefore, we define the types of key and value as string types.

map operation

We will follow the above small case to use the operation here.

  1. Access and replication. We can just use the subscript directly.
// assignment
mapName[key] = "value"
userInfo["name"] = "Wang Wu"

// visit
mapName[key]
name := userInfo["name"]
  1. Delete element. To delete, you need to use delete() to pass the key to be deleted to the function.
delete(mapName, key)

delete(userInfo, "name")
  1. Judge whether a value key exists. Above, we can access the key in the map and directly use the subscript. If key1 does not exist in the map, val1 is a null value of value type. This will make it impossible for us to distinguish whether the key does not exist or its corresponding value is null.
value, boolean := mapName[key]
// If boolean is true, the corresponding key exists; if false, the key does not exist.

if value, ok := userInfo["address"]; !ok {
  fmt.Println("address key not found!")
}
because address this key Does not exist, so it will be output“ address key not found!". 
  1. Loop. Loop map is generally implemented by using for range.
// grammar
for value, key := range mapName {
  fmt.Println(key, "=>", value)
}
// Example
for value, key := range userInfo {
    fmt.Println(key, "=>", value)
}
// output
1 => id
 Zhang San => name
12 => age

summary

In fact, the basic operation of map is so simple. Its understanding is also so simple. We often use this type in daily development.

Back to the case of multiple users at the top, do we know how to use map implementation at this time.

  1. Because there are multiple users, do we need to define a multidimensional map structure.
  2. The first level key of a map is int, which represents the current user serial number (increasing from 0, 1, 2, 3... In turn). The value corresponding to the key is the specific information of a user. We also define the map type to store it. Both key and value are strings, and the structure is like the small case in the map declaration.
  3. Because we don't know the specific number of users, we define the first level key as a slice, because the length of the slice is not fixed.
userInfo := make([]map[string]string, 3)

for i := 0; i < 3; i++ {
    userInfo[i] = make(map[string]string, 3)
     userInfo[i]["id"] = "ID"
     userInfo[i]["name"] = "name"
     userInfo[i]["age"] = "Age"
}
fmt.Println(userInfo)

// output
[
  map[id:ID name:name age:Age] 
  map[id:ID name:name age:Age] 
  map[id:ID name:name age:Age]
]

Why make twice? Because slices and map s are reference types in golang. The first time you make, you initialize the memory space for the slice, and the second time you allocate the memory space for the element corresponding to the key of the slice. The general structure is like the following figure.

Posted by pplexr on Sun, 21 Nov 2021 12:53:47 -0800