preface

A Hash table is a clever and useful data structure. It is an unordered collection of key/value pairs in which all keys are different and values can be retrieved, updated, or deleted in constant time complexity with a given key. A Map is a reference to a Hash table that quickly retrieves data based on keys that, like an index, point to the value associated with that key. I’ll talk about the basics of a Map at a later time, but teaching you how to use a Map will be the focus of this section. Remember that a Map stores an unordered set of key-value pairs.

Create and initialize

usemakefunction

Make can be used to create slices or maps. Here’s the rule:

m := make(map[keyType]valueType)
Copy the code

Let’s try to create:

month := make(map[string]int)
month["January"] = 1
month["February"] = 2
month["March"] = 3
Copy the code

The first line creates an empty Map Month with a key of type string and a value of type int, and then assigns three key-value pairs to month.

Use literals

The above code can be implemented literally:

month := map[string]int{"January":1."February":2."March":3}
// It could be written like this
month := map[string]int{
	"January":1."February":2."March":3,}Copy the code

It is also possible to create an empty Map using literals, without assigning a value inside the braces:

month := map[string]int{}
fmt.Println(month)        // output: map[]
Copy the code

Empty Map, is there a nil Map? Maps with nil, of course:

var month map[string]int
fmt.Println(month == nil)    // Output: true
Copy the code

Panic: Assignment to Entry in nil map can’t access key-value pairs. We can initialize it using the mentioned make function:

var month map[string]int
month = make(map[string]int)
month["January"] = 1
fmt.Println(month)   // Output: map[January:1]
Copy the code

As you might expect, the zero value of a Map is nil, and a Map is a reference to the underlying Hash table. Map keys can be either built-in types or structural types, as long as they can be compared using the == operator. Slicing, functions, and structure types that contain slicing cannot be used as keys due to reference semantics. Using these types causes compilation errors:

month := map[[]string]int{}
// Compile error: invalid map key type []string
Copy the code

There is no type restriction for a Map value, and there is certainly no reason to prevent users from using slices as Map values:

m := map[string] []int{}
slice := []int{1.2.3}
m["slice"] = slice
fmt.Println(m["slice"])

/ / or
slice := []int{1.2.3}
m := map[string] []int{"slice":slice}
fmt.Println(m["slice"])
Copy the code

The first code creates an empty Map with a key of type string and a value of type slice, and then assigns the slice to a key named slice. The second piece of code is a shortened version of the first.

How to useMap

Maps are easy to use, similar to arrays, where arrays use indexes and maps use keys to retrieve or modify values.

m := map[string]int{}
m["January"] = 1        / / assignment
fmt.Println(m)			// Output: map[January:1]
m["January"] = 10       / / modify
fmt.Println(m)          // Output: map[January:10]
january := m["January"]   / / get the value
fmt.Println(january)     // Output: 10
Copy the code

If the key already exists, the new value overwrites the old value, as shown above, so the key is not allowed to be duplicated. When we get the value of a nonexistent key, we return the zero value of the value type. In this case, we do not know whether there is a zero-value key-value pair or whether the key-value pair does not exist at all. Fortunately, Map gives us a way to:

february,exists := m["February"]
fmt.Println(february,exists)   // Output: 0 false
Copy the code

The first return value is value, and the second return value is Boolean variable, indicating whether value exists. This makes it easy to determine whether a key exists or not.

delete— Delete key-value pairs

Unlike Slice, Go provides us with the ability to delete key-value pairs — the delete function. Function prototype:

func delete(m map[Type]Type1, key Type)
Copy the code

The first parameter is Map and the second parameter is key.

m := map[string]int{
	"January":1."February":2."March":3,
}
fmt.Println(m)     // Output: map[March:3 January:1 February:2]
delete(m,"January")
fmt.Println(m)     // Output: map[February:2 March:3]
Copy the code

The delete function does nothing to delete a nonexistent key-value pair.

traverseMap

Maps can’t be iterated over with a for loop, just like arrays and slices can be iterated over with a range.

for key, value := range m {
	fmt.Println(key, "= >", value)
}
Copy the code

Output:

February => 2
March => 3
January => 1
Copy the code

The blank operator _ can be used to ignore the returned key or value. As you execute the code several times, you will notice that the order of return values may be different, meaning that the Map is traversed out of order.

lenfunction

We can use len to return the number of key-value pairs in the Map:

fmt.Println("len(m) =".len(m))
Copy the code

MapIs a reference type

A Map is a reference to underlying data. The process of writing code involves Map copying, passing maps between functions, and so on. Like Slice, the underlying data pointed to by a Map is not copied.

m := map[string]int{
	"January":1."February":2."March":3,
}
month := m    
delete(month,"February")
fmt.Println(m)
fmt.Println(month)
Copy the code

Output:

map[January:1 March:3]
map[January:1 March:3]
Copy the code

In the preceding code, Map M is assigned to Month, and a key-value pair is deleted from month, and M is changed. This indicates that m and Month share the underlying data when a Map is copied. Changing one of the underlying data changes the other. Similarly, when a Map is passed between functions, it is actually a reference to the Map and does not involve the copy of underlying data. If the Map is modified in the called function, the calling function will also be aware of the Map change. What if I really want to copy a Map?

month := map[string]int{}
m := map[string]int{
	"January":1."February":2."March":3,}for key,value := range m{
	month[key] = value
}
delete(month,"February")
fmt.Println(m)
fmt.Println(month)
Copy the code

Output:

map[January:1 February:2 March:3]
map[January:1 March:3]
Copy the code

In the code above, we use range to loop m to Month, and then delete one of month’s key-value pairs. The printed result shows that M has not changed. This enables a true copy. So much for the use of Map, we welcome your comments!


Original article, if need to be reproduced, please indicate the source! Check out “Golang is coming” or go to seekload.net for more great articles.

The public account “Golang is coming” has prepared a mystery learning gift package for you, and the background replies [ebook] to get it!