# golang go语言_在Go中了解地图

golang go语言

Most modern programming languages have the concept of a dictionary or a hash type. These types are commonly used to store data in pairs with a key that maps to a value.

In Go, the map data type is what most programmers would think of as the dictionary type. It maps keys to values, making key-value pairs that are a useful way to store data in Go. A map is constructed by using the keyword map followed by the key data type in square brackets [ ], followed by the value data type. The key-value pairs are then placed inside curly braces on either side { }:

map[key]value{}

You typically use maps in Go to hold related data, such as the information contained in an ID. A map with data looks like this:

map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}

In addition to the curly braces, there are also colons throughout the map that connect the key-value pairs. The words to the left of the colons are the keys. Keys can be any comparable type in Go, like strings, ints, and so on.

The keys in the example map are:

• "name"

"name"

• "animal"

"animal"

• "color"

"color"

• "location"

"location"

The words to the right of the colons are the values. Values can be any data type. The values in the example map are:

• "Sammy"

"Sammy"

• "shark"

"shark"

• "blue"

"blue"

• "ocean"

"ocean"

Like the other data types, you can store the map inside a variable, and print it out:

sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}
fmt.Println(sammy)



Output
map[animal:shark color:blue location:ocean name:Sammy]


The order of the key-value pairs may have shifted. In Go, the map data type is unordered. Regardless of the order, the key-value pairs will remain intact, enabling you to access data based on their relational meaning.

## 访问地图项 (Accessing Map Items)

You can call the values of a map by referencing the related keys. Since maps offer key-value pairs for storing data, they can be important and useful items in your Go program.

If you want to isolate Sammy’s username, you can do so by calling sammy["name"]; the variable holding your map and the related key. Let’s print that out:

fmt.Println(sammy["name"])

And receive the value as output:



Output
Sammy


Maps behave like a database; instead of calling an integer to get a particular index value as you would with a slice, you assign a value to a key and call that key to get its related value.

By invoking the key "name" you receive the value of that key, which is "Sammy".

Similarly you can call the remaining values in the sammy map using the same format:

fmt.Println(sammy["animal"])
// returns shark

fmt.Println(sammy["color"])
// returns blue

fmt.Println(sammy["location"])
// returns ocean

By making use of the key-value pairs in map data types, you can reference keys to retrieve values.

## 键和值 (Keys and Values)

Unlike some programming languages, Go does not have any convenience functions to list out the keys or values of a map. An example of this would be Python’s .keys() method for dictionaries. It does, however, allow for iteration by using the range operator:

for key, value := range sammy {
fmt.Printf("%q is the key for the value %q\n", key, value)
}

When ranging through a map in Go, it’ll return two values. The first value will be the key, and the second value will be the value. Go will create these variables with the correct data type. In this case, the map key was a string so key will also be a string. The value is also a string:



Output
"animal" is the key for the value "shark"
"color" is the key for the value "blue"
"location" is the key for the value "ocean"
"name" is the key for the value "Sammy"


To get a list of just the keys, you can use the range operator again. You can declare just one variable to only access the keys:

keys := []string{}

for key := range sammy {
keys = append(keys, key)
}
fmt.Printf("%q", keys)

The program begins by declaring a slice to store your keys in.

The output will show only the keys of your map:



Output
["color" "location" "name" "animal"]


Again, the keys are not sorted. If you want to sort them, you use the sort.Strings function from the sort package:

sort.Strings(keys)

With this function, you’ll receive the following output:



Output
["animal" "color" "location" "name"]


You can use the same pattern to retrieve just the values in a map. In the next example, you pre-allocate the slice to avoid allocations, thus making the program more efficient:

sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}

items := make([]string, len(sammy))

var i int

for _, v := range sammy {
items[i] = v
i++
}
fmt.Printf("%q", items)

First you declare a slice to store your keys in; since you know how many items you need, you can avoid potential memory allocations by defining the slice at the exact same size. You then declare your index variable. As you don’t want the key, you use the _ operator, when starting your loop, to ignore the key’s value. Your output would be the following:



Output
["ocean" "Sammy" "shark" "blue"]


To determine the number of items in a map, you can use the built-in len function:

sammy := map[string]string{"name": "Sammy", "animal": "shark", "color": "blue", "location": "ocean"}
fmt.Println(len(sammy))

The output displays the number of items in your map:



Output
4


Even though Go doesn’t ship with convenience functions to get keys and values, it only takes a few lines of code to retrieve the keys and values when needed.

## 检查存在性 (Checking Existence)

Maps in Go will return the zero value for the value type of the map when the requested key is missing. Because of this, you need an alternative way to differentiate a stored zero, versus a missing key.

Let’s look up a value in a map that you know doesn’t exist and look at the value returned:

counts := map[string]int{}
fmt.Println(counts["sammy"])

You’ll see the following output:



Output
0


Even though the key sammy was not in the map, Go still returned the value of 0. This is because the value data type is an int, and because Go has a zero value for all variables, it returns the zero value of 0.

In many cases, this is undesirable and would lead to a bug in your program. When looking up the value in a map, Go can return a second, optional value. This second value is a bool and will be true if the key was found, or false if the key was not found. In Go, this is referred to as the ok idiom. Even though you could name the variable that captures the second argument anything you want, in Go, you always name it ok:

count, ok := counts["sammy"]

If the key sammy exists in the counts map, then ok will be true. Otherwise ok will be false.

You can use the ok variable to decide what to do in your program:

if ok {
fmt.Printf("Sammy has a count of %d\n", count)
} else {
}

This would result in the following output:



Output


In Go, you can combine variable declaration and conditional checking with an if/else block. This allows you to use a single statement for this check:

if count, ok := counts["sammy"]; ok {
fmt.Printf("Sammy has a count of %d\n", count)
} else {
}

When retrieving a value from a map in Go, it’s always good practice to check for its existence as well to avoid bugs in your program.

## 修改地图 (Modifying Maps)

Maps are a mutable data structure, so you can modify them. Let’s look at adding and deleting map items in this section.

### 添加和更改地图项 (Adding and Changing Map Items)

Without using a method or function, you can add key-value pairs to maps. You do this using the maps variable name, followed by the key value in square brackets [ ], and using the equal = operator to set a new value:

map[key] = value

In practice, you can see this work by adding a key-value pair to a map called usernames:

usernames := map[string]string{"Sammy": "sammy-shark", "Jamie": "mantisshrimp54"}

fmt.Println(usernames)

The output will display the new Drew:squidly key-value pair in the map:



Output
map[Drew:squidly Jamie:mantisshrimp54 Sammy:sammy-shark]


Because maps are returned unordered, this pair may occur anywhere in the map output. If you use the usernames map later in your program file, it will include the additional key-value pair.

You can also use this syntax for modifying the value assigned to a key. In this case, you reference an existing key and pass a different value to it.

Consider a map called followers that tracks followers of users on a given network. The user "drew" had a bump in followers today, so you need to update the integer value passed to the "drew" key. You’ll use the Println() function to check that the map was modified:

followers := map[string]int{"drew": 305, "mary": 428, "cindy": 918}
followers["drew"] = 342
fmt.Println(followers)

Your output will show the updated value for drew:



Output
map[cindy:918 drew:342 mary:428]


You see that the number of followers jumped from the integer value of 305 to 342.

You can use this method for adding key-value pairs to maps with user input. Let’s write a quick program called usernames.go that runs on the command line and allows input from the user to add more names and associated usernames:

package main

import (
"fmt"
"strings"
)

func main() {
usernames := map[string]string{"Sammy": "sammy-shark", "Jamie": "mantisshrimp54"}

for {
fmt.Println("Enter a name:")

var name string
_, err := fmt.Scanln(&name)

if err != nil {
panic(err)
}

name = strings.TrimSpace(name)

if u, ok := usernames[name]; ok {
fmt.Printf("%q is the username of %q\n", u, name)
continue
}

fmt.Printf("I don't have %v's username, what is it?\n", name)

if err != nil {
panic(err)
}

fmt.Println("Data updated.")
}
}

In usernames.go you first define the original map. You then set up a loop to iterate over the names. You request your user to enter a name and declare a variable to store it in. Next, you check to see if you had an error; if so, the program will exit with a panic. Because Scanln captures the entire input, including the carriage return, you need to remove any space from the input; you do this with the strings.TrimSpace function.

usernames.go您首先定义原始地图。 然后，您设置一个循环以遍历名称。 您要求用户输入一个名称，并声明一个变量以将其存储在其中。接下来，检查是否有错误； 如果是这样，程序将以panic退出。 因为Scanln捕获整个输入，包括回车，所以您需要从输入中删除所有空间；因此， 您可以使用strings.TrimSpace函数执行此操作。

The if block checks whether the name is present in the map and prints feedback. If the name is present it then continues back to the top of the loop. If the name is not in the map, it provides feedback to the user and then will ask for a new username for the associated name. The program checks again to see if there is an error. With no error, it trims off the carriage return, assigns the username value to the name key, and then prints feedback that the data was updated.

if块检查名称是否存在于地图中并打印反馈。 如果存在名称，则继续返回循环顶部。 如果名称不在地图中，它将向用户提供反馈，然后将为关联的名称要求新的用户名。 程序再次检查是否有错误。 不会出现错误，它会修剪回车符，将用户名值分配给名称键，然后输出有关数据已更新的反馈。

Let’s run the program on the command line:

You’ll see the following output:



Output
Enter a name:
Sammy
"sammy-shark" is the username of "Sammy"
Enter a name:
Jesse
I don't have Jesse's username, what is it?
JOctopus
Data updated.
Enter a name:


When you’re done testing, press CTRL + C to escape the program.

This shows how you can modify maps interactively. With this particular program, as soon as you exit the program with CTRL + C you’ll lose all your data unless you implement a way to handle reading and writing files.

To summarize, you can add items to maps or modify values with the map[key] = value syntax.

### 删除地图项 (Deleting Map Items)

Just as you can add key-value pairs and change values within the map data type, you can also delete items within a map.

To remove a key-value pair from a map, you can use the built-in function delete(). The first argument is the map you are deleting from. The second argument is the key you are deleting:

delete(map, key)

Let’s define a map of permissions:

permissions := map[int]string{1: "read", 2: "write", 4: "delete", 8: "create", 16:"modify"}

You no longer need the modify permission, so you’ll remove it from your map. Then you’ll print out the map to confirm it was removed:

permissions := map[int]string{1: "read", 2: "write", 4: "delete", 8: "create", 16: "modify"}
delete(permissions, 16)
fmt.Println(permissions)

The output will confirm the deletion:



Output


The line delete(permissions, 16) removes the key-value pair 16:"modify" from the permissions map.

delete(permissions, 16)permissions映射中删除键/值对16:"modify"

If you would like to clear a map of all of its values, you can do so by setting it equal to an empty map of the same type. This will create a new empty map to use, and the old map will be cleared from memory by the garbage collector.

Let’s remove all the items within the permissions map:

permissions = map[int]string{}
fmt.Println(permissions)

The output shows that you now have an empty map devoid of key-value pairs:



Output
map[]


Because maps are mutable data types, they can be added to, modified, and have items removed and cleared.

## 结论 (Conclusion)

This tutorial explored the map data structure in Go. Maps are made up of key-value pairs and provide a way to store data without relying on indexing. This allows us to retrieve values based on their meaning and relation to other data types.

golang go语言

07-09 400
05-08
06-29 275
06-29 2843
04-23 1817
08-14 211
08-09 629
06-27 1177
06-27 133
08-20 1194
06-22 5万+
03-02 206
09-10 69
10-04 2万+
08-12 335
08-13 418
08-29 1916
04-01

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助