This is the 10th day of my participation in Gwen Challenge
Hi, I’m @Luo Zhu
This article was first published on luo Zhu’s official website
This article was translated from Golang Tutorial Series
This article synchronizes in the public account “luo Zhu early teahouse”, reprint please contact the author.
Creation is not easy, form a habit, quality three even!
What is a map?
Map is a built-in type in Go for storing key-value pairs. Let’s take a startup with a few employees. For simplicity, let’s assume that all of these employee names are unique. We are looking for a data structure to store each employee’s salary. For this use case, a map would be a perfect choice. The employee’s name can be a key, and the salary can be a value. Maps are similar to dictionaries in other languages, such as Python.
How to create a Map
You create a map by passing key and value types to the make function. Here is the syntax for creating a new map.
make(map[type of key]type of value)
Copy the code
employeeSalary := make(map[string]int)
Copy the code
The above line creates a map named employeeSalary with a String key and an int value.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := make(map[string]int)
fmt.Println(employeeSalary)
}
Copy the code
Run in Playground
The above program creates a map named employeeSalary with a string key and an int value. The above program will print.
map[]
Copy the code
Since we did not add any elements to the map, it is empty.
Add elements to map
The syntax for adding new elements to a map is the same as the syntax for an array. The following program adds some new employees to the employeeSalary Map.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := make(map[string]int)
employeeSalary["steve"] = 12000
employeeSalary["jamie"] = 15000
employeeSalary["mike"] = 9000
fmt.Println("employeeSalary map contents:", employeeSalary)
}
Copy the code
Run in playground
We’ve added three employees — Steve, Jamie and Mike — and their corresponding salaries.
The above program prints out.
employeeSalary map contents: map[steve:12000 jamie:15000 mike:9000]
Copy the code
You can also initialize a map in the declaration itself.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int {
"steve": 12000."jamie": 15000,
}
employeeSalary["mike"] = 9000
fmt.Println("employeeSalary map contents:", employeeSalary)
}
Copy the code
Run in playground
The above program declares the employeeSalary and adds two elements to the declaration itself. Later, an element with a key of Mike was added. The program prints out
employeeSalary map contents: map[jamie:15000 mike:9000 steve:12000]
Copy the code
It doesn’t have to be a string type to be a key. All comparable types such as Booleans, integers, floating-point, complex numbers, and strings can also be keys. Even user-defined types such as structures can be keys. If you want to learn more about comparative types, visit golang.org/ref/spec#Co…
The map of zero value
The zero value of map is nil. If you try to add elements to a nil map, a runtime panic will occur. Therefore, before adding elements, the map must be initialized.
package main
func main(a) {
var employeeSalary map[string]int
employeeSalary["steve"] = 12000
}
Copy the code
Run in playground
In the above program, employeeSalary is nil, and we try to add a new key to the map. The program will have an error
panic: assignment to entry in nil map
Retrieves a key value from the map
Now that we have added some elements to the map, let’s learn how to retrieve them. Map [key] is the syntax for retrieving map elements.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int{
"steve": 12000."jamie": 15000."mike": 9000,
}
employee := "jamie"
salary := employeeSalary[employee]
fmt.Println("Salary of", employee, "is", salary)
}
Copy the code
Run in playground
The above procedure is very straightforward. Employee Jamie’s salary is retrieved and printed. The program prints
Salary of jamie is 15000
Copy the code
What happens if an element doesn’t exist? Map will return a zero value for the element’s type. In the example of the employeeSalary map, if we attempt to access an element that does not exist, we return the zero value of int, that is, 0.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int{
"steve": 12000."jamie": 15000,
}
fmt.Println("Salary of joe is", employeeSalary["joe"])}Copy the code
Run in playground
The output of the above program is
Salary of joe is 0
Copy the code
The above program returns Joe’s salary as 0. There will be no runtime error when we try to retrieve the value of a key that does not exist in the map.
Checking if a key exists
In the previous section, we learned that when a key does not exist, a zero value of that type is returned. This does not help when we want to know if the key really exists in the map.
For example, we want to know if a key exists in the employeeSalary Map.
value, ok := map[key]
Copy the code
This is the syntax for finding out if a particular key exists in the map. If OK is true, the key exists and its value is in the variable value, otherwise it does not exist.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int{
"steve": 12000."jamie": 15000,
}
newEmp := "joe"
value, ok := employeeSalary[newEmp]
if ok == true {
fmt.Println("Salary of", newEmp, "is", value)
return
}
fmt.Println(newEmp, "not found")}Copy the code
Run in playground
In the above program, OK will be false because Joe does not exist. Therefore, the program will print.
joe not found
Copy the code
Iterate over all the elements in a map
The range form of the for loop is used to traverse all elements of a map.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int{
"steve": 12000."jamie": 15000."mike": 9000,
}
fmt.Println("Contents of the map")
for key, value := range employeeSalary {
fmt.Printf("employeeSalary[%s] = %dn", key, value)
}
}
Copy the code
Run in playground
The output of the above program.
Contents of the map
employeeSalary[mike] = 9000
employeeSalary[steve] = 12000
employeeSalary[jamie] = 15000
Copy the code
An important fact is that when using for range, the order in which values are retrieved from the map is not guaranteed to be the same in each execution of the program. It is also different from the order in which elements are added to the map
Removes elements from the map
Delete (map, key) is the syntax for deleting a key from a map. The delete function does not return any value.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int{
"steve": 12000."jamie": 15000."mike": 9000,
}
fmt.Println("map before deletion", employeeSalary)
delete(employeeSalary, "steve")
fmt.Println("map after deletion", employeeSalary)
}
Copy the code
Run in playground
The above program removes the key Steve and prints it
map before deletion map[steve:12000 jamie:15000 mike:9000]
map after deletion map[mike:9000 jamie:15000]
Copy the code
If we try to remove a key that does not exist in the map, there will be no runtime error.
Structure map
So far, we’ve only stored employees’ salaries on the map. Wouldn’t it be great if we could also store every employee’s country on the map? This can be done by using a structure map. Employees can be represented as a structure containing salary and country fields, which are stored in the Map as string keys and structure values. Let’s write a program to see how to do this.
package main
import (
"fmt"
)
type employee struct {
salary int
country string
}
func main(a) {
emp1 := employee{
salary: 12000,
country: "USA",
}
emp2 := employee{
salary: 14000,
country: "Canada",
}
emp3 := employee{
salary: 13000,
country: "India",
}
employeeInfo := map[string]employee{
"Steve": emp1,
"Jamie": emp2,
"Mike": emp3,
}
for name, info := range employeeInfo {
fmt.Printf("Employee: %s Salary:$%d Country: %s\n", name, info.salary, info.country)
}
}
Copy the code
Run in playground
In the above program, the Employee structure contains salary and country fields. We created three employees emp1, emp2, and emp3.
We initialize a map of key type String and value type Employee with the three employees we created.
This program will print.
Employee: Mike Salary:$13000 Country: India
Employee: Steve Salary:$12000 Country: USA
Employee: Jamie Salary:$14000 Country: Canada
Copy the code
The length of the map
The length of a map can be determined using the len function.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int{
"steve": 12000."jamie": 15000,
}
fmt.Println("length is".len(employeeSalary))
}
Copy the code
Run in playground
Len (employeeSalary) in the above program returns the map length. The above program prints out.
length is 2
Copy the code
Map is a reference type
Like slices, a map is a reference type. When a map is assigned to a new variable, they all point to the same internal data structure. Thus, changes in one will be reflected in the other.
package main
import (
"fmt"
)
func main(a) {
employeeSalary := map[string]int{
"steve": 12000."jamie": 15000."mike": 9000,
}
fmt.Println("Original employee salary", employeeSalary)
modified := employeeSalary
modified["mike"] = 18000
fmt.Println("Employee salary changed", employeeSalary)
}
Copy the code
Run in playground
In the above program, employeeSalary is assigned to Modified. In the next line, Mike’s salary is changed to 18000 in the Modified Map. Mike’s salary is now 18,000 in employeeSalary. The program output.
Original employee salary map[jamie:15000 mike:9000 steve:12000]
Employee salary changed map[jamie:15000 mike:18000 steve:12000]
Copy the code
The same is true when a map is passed to a function as an argument. When any changes are made to the map in a function, it is also visible to the caller.
The map equality
Maps cannot be compared using the == operator. == can only be used to check if a map is nil.
package main
func main(a) {
map1 := map[string]int{
"one": 1."two": 2,
}
map2 := map1
if map1 == map2 {
}
}
Copy the code
Run in playground
The above program will not compile with an error
invalid operation: map1 == map2 (map can only be compared to nil)
Copy the code
One way to check if two maps are equal is to compare each element of each map one by one. Another approach is to use reflection. I encourage you to write a program for this and make it work.
I’ve put together a program of all the concepts we’ve discussed. You can download it from Github.
This concludes the tutorial. I hope you like it. Please leave a comment.